This commit is contained in:
J. Duke 2017-07-05 22:08:15 +02:00
commit 637fc0b863
127 changed files with 4363 additions and 1530 deletions

View File

@ -375,3 +375,4 @@ f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129
d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130 d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130
8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131 8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131
a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132 a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132
be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133

View File

@ -535,3 +535,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130 7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130
943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131 943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131
713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132 713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132
a25e0fb6033245ab075136e744d362ce765464cd jdk-9+133

View File

@ -316,12 +316,8 @@ size_t G1Analytics::predict_pending_cards() const {
return get_new_size_prediction(_pending_cards_seq); return get_new_size_prediction(_pending_cards_seq);
} }
double G1Analytics::oldest_known_gc_end_time_sec() const {
return _recent_prev_end_times_for_all_gcs_sec->oldest();
}
double G1Analytics::last_known_gc_end_time_sec() const { double G1Analytics::last_known_gc_end_time_sec() const {
return _recent_prev_end_times_for_all_gcs_sec->last(); return _recent_prev_end_times_for_all_gcs_sec->oldest();
} }
void G1Analytics::update_recent_gc_times(double end_time_sec, void G1Analytics::update_recent_gc_times(double end_time_sec,

View File

@ -155,7 +155,6 @@ public:
void update_recent_gc_times(double end_time_sec, double elapsed_ms); void update_recent_gc_times(double end_time_sec, double elapsed_ms);
void compute_pause_time_ratio(double interval_ms, double pause_time_ms); void compute_pause_time_ratio(double interval_ms, double pause_time_ms);
double oldest_known_gc_end_time_sec() const;
double last_known_gc_end_time_sec() const; double last_known_gc_end_time_sec() const;
}; };

View File

@ -28,7 +28,6 @@
#include "classfile/symbolTable.hpp" #include "classfile/symbolTable.hpp"
#include "code/codeCache.hpp" #include "code/codeCache.hpp"
#include "code/icBuffer.hpp" #include "code/icBuffer.hpp"
#include "gc/g1/g1Analytics.hpp"
#include "gc/g1/bufferingOopClosure.hpp" #include "gc/g1/bufferingOopClosure.hpp"
#include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/concurrentG1Refine.hpp"
#include "gc/g1/concurrentG1RefineThread.hpp" #include "gc/g1/concurrentG1RefineThread.hpp"
@ -2474,19 +2473,8 @@ size_t G1CollectedHeap::max_capacity() const {
} }
jlong G1CollectedHeap::millis_since_last_gc() { jlong G1CollectedHeap::millis_since_last_gc() {
jlong now = os::elapsed_counter() / NANOSECS_PER_MILLISEC; // assert(false, "NYI");
const G1Analytics* analytics = _g1_policy->analytics(); return 0;
double last = analytics->last_known_gc_end_time_sec();
jlong ret_val = now - (last * 1000);
if (ret_val < 0) {
// See the notes in GenCollectedHeap::millis_since_last_gc()
// for more information about the implementation.
log_warning(gc)("Detected clock going backwards. "
"Milliseconds since last GC would be " JLONG_FORMAT
". returning zero instead.", ret_val);
return 0;
}
return ret_val;
} }
void G1CollectedHeap::prepare_for_verify() { void G1CollectedHeap::prepare_for_verify() {

View File

@ -604,7 +604,7 @@ void G1DefaultPolicy::record_collection_pause_end(double pause_time_ms, size_t c
_analytics->report_alloc_rate_ms(alloc_rate_ms); _analytics->report_alloc_rate_ms(alloc_rate_ms);
double interval_ms = double interval_ms =
(end_time_sec - _analytics->oldest_known_gc_end_time_sec()) * 1000.0; (end_time_sec - _analytics->last_known_gc_end_time_sec()) * 1000.0;
_analytics->update_recent_gc_times(end_time_sec, pause_time_ms); _analytics->update_recent_gc_times(end_time_sec, pause_time_ms);
_analytics->compute_pause_time_ratio(interval_ms, pause_time_ms); _analytics->compute_pause_time_ratio(interval_ms, pause_time_ms);
} }

View File

@ -1256,21 +1256,21 @@ class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure {
}; };
jlong GenCollectedHeap::millis_since_last_gc() { jlong GenCollectedHeap::millis_since_last_gc() {
// javaTimeNanos() is guaranteed to be monotonically non-decreasing // We need a monotonically non-decreasing time in ms but
// provided the underlying platform provides such a time source // os::javaTimeMillis() does not guarantee monotonicity.
// (and it is bug free). So we still have to guard against getting
// back a time later than 'now'.
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
GenTimeOfLastGCClosure tolgc_cl(now); GenTimeOfLastGCClosure tolgc_cl(now);
// iterate over generations getting the oldest // iterate over generations getting the oldest
// time that a generation was collected // time that a generation was collected
generation_iterate(&tolgc_cl, false); generation_iterate(&tolgc_cl, false);
// javaTimeNanos() is guaranteed to be monotonically non-decreasing
// provided the underlying platform provides such a time source
// (and it is bug free). So we still have to guard against getting
// back a time later than 'now'.
jlong retVal = now - tolgc_cl.time(); jlong retVal = now - tolgc_cl.time();
if (retVal < 0) { if (retVal < 0) {
log_warning(gc)("Detected clock going backwards. " NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);)
"Milliseconds since last GC would be " JLONG_FORMAT
". returning zero instead.", retVal);
return 0; return 0;
} }
return retVal; return retVal;

View File

@ -375,3 +375,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123
6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130 6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130
8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131 8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131
d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132 d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
3cdae27c90b5e41afe75eab904fda19fac076330 jdk-9+133

View File

@ -34,7 +34,7 @@ include GendataTZDB.gmk
include GendataBlacklistedCerts.gmk include GendataBlacklistedCerts.gmk
include GendataPolicyJars.gmk include GendataCryptoPolicy.gmk
################################################################################ ################################################################################
@ -64,13 +64,19 @@ TARGETS += $(GENDATA_CURDATA)
GENDATA_JAVA_SECURITY_SRC := $(JDK_TOPDIR)/src/java.base/share/conf/security/java.security GENDATA_JAVA_SECURITY_SRC := $(JDK_TOPDIR)/src/java.base/share/conf/security/java.security
GENDATA_JAVA_SECURITY := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/java.security GENDATA_JAVA_SECURITY := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/java.security
ifeq ($(UNLIMITED_CRYPTO), true)
CRYPTO.POLICY := unlimited
else
CRYPTO.POLICY := limited
endif
# RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile # RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile
$(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC) $(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC)
$(call LogInfo, Generating java.security) $(call LogInfo, Generating java.security)
$(call MakeDir, $(@D)) $(call MakeDir, $(@D))
$(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \ $(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \
$(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC) $(OPENJDK_TARGET_CPU_ARCH) $(CRYPTO.POLICY) $(RESTRICTED_PKGS_SRC)
TARGETS += $(GENDATA_JAVA_SECURITY) TARGETS += $(GENDATA_JAVA_SECURITY)

View 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 \
################################################################################

View File

@ -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))

View File

@ -36,3 +36,9 @@ $(eval $(call SetupBuildLauncher, jdeps, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
)) ))
$(eval $(call SetupBuildLauncher, jdeprscan, \
MAIN_CLASS := com.sun.tools.jdeprscan.Main, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
))

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -38,8 +38,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \ CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
$(LIBJAVA_HEADER_FLAGS) \ $(LIBJAVA_HEADER_FLAGS) \
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.pkcs11, \ -I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.pkcs11, \
DISABLED_WARNINGS_solstudio := E_DECLARATION_IN_CODE, \
DISABLED_WARNINGS_microsoft := 4013 4267, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \ LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \ $(call SET_SHARED_LIBRARY_ORIGIN), \

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -35,7 +35,8 @@ import java.util.*;
* *
* 1. Adds additional packages to the package.access and * 1. Adds additional packages to the package.access and
* package.definition security properties. * package.definition security properties.
* 2. Filter out platform-unrelated parts * 2. Filter out platform-unrelated parts.
* 3. Set the JCE jurisdiction policy directory.
* *
* In order to easily maintain platform-related entries, every item * In order to easily maintain platform-related entries, every item
* (including the last line) in package.access and package.definition * (including the last line) in package.access and package.definition
@ -50,12 +51,13 @@ public class MakeJavaSecurity {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if (args.length < 4) { if (args.length < 5) {
System.err.println("Usage: java MakeJavaSecurity " + System.err.println("Usage: java MakeJavaSecurity " +
"[input java.security file name] " + "[input java.security file name] " +
"[output java.security file name] " + "[output java.security file name] " +
"[openjdk target os] " + "[openjdk target os] " +
"[openjdk target cpu architecture]" + "[openjdk target cpu architecture]" +
"[JCE jurisdiction policy directory]" +
"[more restricted packages file name?]"); "[more restricted packages file name?]");
System.exit(1); System.exit(1);
@ -63,8 +65,8 @@ public class MakeJavaSecurity {
// more restricted packages // more restricted packages
List<String> extraLines; List<String> extraLines;
if (args.length == 5) { if (args.length == 6) {
extraLines = Files.readAllLines(Paths.get(args[4])); extraLines = Files.readAllLines(Paths.get(args[5]));
} else { } else {
extraLines = Collections.emptyList(); extraLines = Collections.emptyList();
} }
@ -135,6 +137,16 @@ public class MakeJavaSecurity {
} }
} }
// Set the JCE policy value
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
int index = line.indexOf("crypto.policydir-tbd");
if (index >= 0) {
String prefix = line.substring(0, index);
lines.set(i, prefix + args[4]);
}
}
// Clean up the last line of PKG_ACC and PKG_DEF blocks. // Clean up the last line of PKG_ACC and PKG_DEF blocks.
// Not really necessary since a blank line follows. // Not really necessary since a blank line follows.
boolean inBlock = false; boolean inBlock = false;

View File

@ -986,8 +986,9 @@ final class CipherCore {
if (padding != null) { if (padding != null) {
int padStart = padding.unpad(outWithPadding, 0, outLen); int padStart = padding.unpad(outWithPadding, 0, outLen);
if (padStart < 0) { if (padStart < 0) {
throw new BadPaddingException("Given final block not " throw new BadPaddingException("Given final block not " +
+ "properly padded"); "properly padded. Such issues can arise if a bad key " +
"is used during decryption.");
} }
outLen = padStart; outLen = padStart;
} }

View File

@ -331,12 +331,6 @@ public final class Class<T> implements java.io.Serializable,
* Note that this method does not check whether the requested class * Note that this method does not check whether the requested class
* is accessible to its caller. * is accessible to its caller.
* *
* <p> If the {@code loader} is {@code null}, and a security
* manager is present, and the caller's class loader is not null, then this
* method calls the security manager's {@code checkPermission} method
* with a {@code RuntimePermission("getClassLoader")} permission to
* ensure it's ok to access the bootstrap class loader.
*
* @param name fully qualified name of the desired class * @param name fully qualified name of the desired class
* @param initialize if {@code true} the class will be initialized. * @param initialize if {@code true} the class will be initialized.
* See Section 12.4 of <em>The Java Language Specification</em>. * See Section 12.4 of <em>The Java Language Specification</em>.
@ -348,6 +342,11 @@ public final class Class<T> implements java.io.Serializable,
* by this method fails * by this method fails
* @exception ClassNotFoundException if the class cannot be located by * @exception ClassNotFoundException if the class cannot be located by
* the specified class loader * the specified class loader
* @exception SecurityException
* if a security manager is present, and the {@code loader} is
* {@code null}, and the caller's class loader is not
* {@code null}, and the caller does not have the
* {@link RuntimePermission}{@code ("getClassLoader")}
* *
* @see java.lang.Class#forName(String) * @see java.lang.Class#forName(String)
* @see java.lang.ClassLoader * @see java.lang.ClassLoader
@ -782,22 +781,17 @@ public final class Class<T> implements java.io.Serializable,
* null in such implementations if this class was loaded by the bootstrap * null in such implementations if this class was loaded by the bootstrap
* class loader. * class loader.
* *
* <p> If a security manager is present, and the caller's class loader is
* not null and the caller's class loader is not the same as or an ancestor of
* the class loader for the class whose class loader is requested, then
* this method calls the security manager's {@code checkPermission}
* method with a {@code RuntimePermission("getClassLoader")}
* permission to ensure it's ok to access the class loader for the class.
*
* <p>If this object * <p>If this object
* represents a primitive type or void, null is returned. * represents a primitive type or void, null is returned.
* *
* @return the class loader that loaded the class or interface * @return the class loader that loaded the class or interface
* represented by this object. * represented by this object.
* @throws SecurityException * @throws SecurityException
* if a security manager exists and its * if a security manager is present, and the caller's class loader
* {@code checkPermission} method denies * is not {@code null} and is not the same as or an ancestor of the
* access to the class loader for the class. * class loader for the class whose class loader is requested,
* and the caller does not have the
* {@link RuntimePermission}{@code ("getClassLoader")}
* @see java.lang.ClassLoader * @see java.lang.ClassLoader
* @see SecurityManager#checkPermission * @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission * @see java.lang.RuntimePermission

View File

@ -1537,22 +1537,13 @@ public abstract class ClassLoader {
* will return <tt>null</tt> in such implementations if this class loader's * will return <tt>null</tt> in such implementations if this class loader's
* parent is the bootstrap class loader. * parent is the bootstrap class loader.
* *
* <p> If a security manager is present, and the invoker's class loader is
* not <tt>null</tt> and is not an ancestor of this class loader, then this
* method invokes the security manager's {@link
* SecurityManager#checkPermission(java.security.Permission)
* <tt>checkPermission</tt>} method with a {@link
* RuntimePermission#RuntimePermission(String)
* <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
* access to the parent class loader is permitted. If not, a
* <tt>SecurityException</tt> will be thrown. </p>
*
* @return The parent <tt>ClassLoader</tt> * @return The parent <tt>ClassLoader</tt>
* *
* @throws SecurityException * @throws SecurityException
* If a security manager exists and its <tt>checkPermission</tt> * If a security manager is present, and the caller's class loader
* method doesn't allow access to this class loader's parent class * is not {@code null} and is not an ancestor of this class loader,
* loader. * and the caller does not have the
* {@link RuntimePermission}{@code ("getClassLoader")}
* *
* @since 1.2 * @since 1.2
*/ */
@ -1590,12 +1581,11 @@ public abstract class ClassLoader {
* @return The platform {@code ClassLoader}. * @return The platform {@code ClassLoader}.
* *
* @throws SecurityException * @throws SecurityException
* If a security manager exists and the caller's class loader is * If a security manager is present, and the caller's class loader is
* not {@code null} and the caller's class loader is not the same * not {@code null}, and the caller's class loader is not the same
* as or an ancestor of the platform class loader, * as or an ancestor of the platform class loader,
* and the {@link SecurityManager#checkPermission(java.security.Permission) * and the caller does not have the
* checkPermission} method denies {@code RuntimePermission("getClassLoader")} * {@link RuntimePermission}{@code ("getClassLoader")}
* to access the platform class loader.
* *
* @since 9 * @since 9
*/ */
@ -1636,17 +1626,6 @@ public abstract class ClassLoader {
* If circular initialization of the system class loader is detected then * If circular initialization of the system class loader is detected then
* an unspecified error or exception is thrown. * an unspecified error or exception is thrown.
* *
* <p> If a security manager is present, and the invoker's class loader is
* not <tt>null</tt> and the invoker's class loader is not the same as or
* an ancestor of the system class loader, then this method invokes the
* security manager's {@link
* SecurityManager#checkPermission(java.security.Permission)
* <tt>checkPermission</tt>} method with a {@link
* RuntimePermission#RuntimePermission(String)
* <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
* access to the system class loader. If not, a
* <tt>SecurityException</tt> will be thrown. </p>
*
* @implNote The system property to override the system class loader is not * @implNote The system property to override the system class loader is not
* examined until the VM is almost fully initialized. Code that executes * examined until the VM is almost fully initialized. Code that executes
* this method during startup should take care not to cache the return * this method during startup should take care not to cache the return
@ -1656,8 +1635,10 @@ public abstract class ClassLoader {
* <tt>null</tt> if none * <tt>null</tt> if none
* *
* @throws SecurityException * @throws SecurityException
* If a security manager exists and its <tt>checkPermission</tt> * If a security manager is present, and the caller's class loader
* method doesn't allow access to the system class loader. * is not {@code null} and is not the same as or an ancestor of the
* system class loader, and the caller does not have the
* {@link RuntimePermission}{@code ("getClassLoader")}
* *
* @throws IllegalStateException * @throws IllegalStateException
* If invoked recursively during the construction of the class * If invoked recursively during the construction of the class

View File

@ -1370,8 +1370,13 @@ public final class Math {
* result is positive zero. * result is positive zero.
* <li>If the argument is infinite, the result is positive infinity. * <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul> * <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression: *
* <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))} * @apiNote As implied by the above, one valid implementation of
* this method is given by the expression below which computes a
* {@code float} with the same exponent and significand as the
* argument but with a guaranteed zero sign bit indicating a
* positive value:<br>
* {@code Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a))}
* *
* @param a the argument whose absolute value is to be determined * @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument. * @return the absolute value of the argument.
@ -1389,8 +1394,13 @@ public final class Math {
* is positive zero. * is positive zero.
* <li>If the argument is infinite, the result is positive infinity. * <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul> * <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression: *
* <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)} * @apiNote As implied by the above, one valid implementation of
* this method is given by the expression below which computes a
* {@code double} with the same exponent and significand as the
* argument but with a guaranteed zero sign bit indicating a
* positive value:<br>
* {@code Double.longBitsToDouble((Double.doubleToRawLongBits(a)<<1)>>>1)}
* *
* @param a the argument whose absolute value is to be determined * @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument. * @return the absolute value of the argument.

View File

@ -1070,8 +1070,13 @@ public final class StrictMath {
* result is positive zero. * result is positive zero.
* <li>If the argument is infinite, the result is positive infinity. * <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul> * <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression: *
* <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))} * @apiNote As implied by the above, one valid implementation of
* this method is given by the expression below which computes a
* {@code float} with the same exponent and significand as the
* argument but with a guaranteed zero sign bit indicating a
* positive value: <br>
* {@code Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a))}
* *
* @param a the argument whose absolute value is to be determined * @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument. * @return the absolute value of the argument.
@ -1089,8 +1094,13 @@ public final class StrictMath {
* is positive zero. * is positive zero.
* <li>If the argument is infinite, the result is positive infinity. * <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul> * <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression: *
* <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)} * @apiNote As implied by the above, one valid implementation of
* this method is given by the expression below which computes a
* {@code double} with the same exponent and significand as the
* argument but with a guaranteed zero sign bit indicating a
* positive value: <br>
* {@code Double.longBitsToDouble((Double.doubleToRawLongBits(a)<<1)>>>1)}
* *
* @param a the argument whose absolute value is to be determined * @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument. * @return the absolute value of the argument.

View File

@ -1507,28 +1507,25 @@ class Thread implements Runnable {
} }
/** /**
* Returns the context ClassLoader for this Thread. The context * Returns the context {@code ClassLoader} for this thread. The context
* ClassLoader is provided by the creator of the thread for use * {@code ClassLoader} is provided by the creator of the thread for use
* by code running in this thread when loading classes and resources. * by code running in this thread when loading classes and resources.
* If not {@linkplain #setContextClassLoader set}, the default is the * If not {@linkplain #setContextClassLoader set}, the default is the
* ClassLoader context of the parent Thread. The context ClassLoader of the * {@code ClassLoader} context of the parent thread. The context
* {@code ClassLoader} of the
* primordial thread is typically set to the class loader used to load the * primordial thread is typically set to the class loader used to load the
* application. * application.
* *
* <p>If a security manager is present, and the invoker's class loader is not
* {@code null} and is not the same as or an ancestor of the context class
* loader, then this method invokes the security manager's {@link
* SecurityManager#checkPermission(java.security.Permission) checkPermission}
* method with a {@link RuntimePermission RuntimePermission}{@code
* ("getClassLoader")} permission to verify that retrieval of the context
* class loader is permitted.
* *
* @return the context ClassLoader for this Thread, or {@code null} * @return the context {@code ClassLoader} for this thread, or {@code null}
* indicating the system class loader (or, failing that, the * indicating the system class loader (or, failing that, the
* bootstrap class loader) * bootstrap class loader)
* *
* @throws SecurityException * @throws SecurityException
* if the current thread cannot get the context ClassLoader * if a security manager is present, and the caller's class loader
* is not {@code null} and is not the same as or an ancestor of the
* context class loader, and the caller does not have the
* {@link RuntimePermission}{@code ("getClassLoader")}
* *
* @since 1.2 * @since 1.2
*/ */

View File

@ -497,6 +497,10 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
String shortTypes = LambdaForm.shortenSignature(types); String shortTypes = LambdaForm.shortenSignature(types);
String className = SPECIES_CLASS_PREFIX + shortTypes; String className = SPECIES_CLASS_PREFIX + shortTypes;
Class<?> c = BootLoader.loadClassOrNull(className); Class<?> c = BootLoader.loadClassOrNull(className);
if (TRACE_RESOLVE) {
System.out.println("[BMH_RESOLVE] " + shortTypes +
(c != null ? " (success)" : " (fail)") );
}
if (c != null) { if (c != null) {
return c.asSubclass(BoundMethodHandle.class); return c.asSubclass(BoundMethodHandle.class);
} else { } else {

View File

@ -492,7 +492,7 @@ class DirectMethodHandle extends MethodHandle {
} }
// Caching machinery for field accessors: // Caching machinery for field accessors:
private static final byte static final byte
AF_GETFIELD = 0, AF_GETFIELD = 0,
AF_PUTFIELD = 1, AF_PUTFIELD = 1,
AF_GETSTATIC = 2, AF_GETSTATIC = 2,
@ -502,7 +502,7 @@ class DirectMethodHandle extends MethodHandle {
AF_LIMIT = 6; AF_LIMIT = 6;
// Enumerate the different field kinds using Wrapper, // Enumerate the different field kinds using Wrapper,
// with an extra case added for checked references. // with an extra case added for checked references.
private static final int static final int
FT_LAST_WRAPPER = Wrapper.COUNT-1, FT_LAST_WRAPPER = Wrapper.COUNT-1,
FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(), FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
FT_CHECKED_REF = FT_LAST_WRAPPER+1, FT_CHECKED_REF = FT_LAST_WRAPPER+1,
@ -515,7 +515,7 @@ class DirectMethodHandle extends MethodHandle {
@Stable @Stable
private static final LambdaForm[] ACCESSOR_FORMS private static final LambdaForm[] ACCESSOR_FORMS
= new LambdaForm[afIndex(AF_LIMIT, false, 0)]; = new LambdaForm[afIndex(AF_LIMIT, false, 0)];
private static int ftypeKind(Class<?> ftype) { static int ftypeKind(Class<?> ftype) {
if (ftype.isPrimitive()) if (ftype.isPrimitive())
return Wrapper.forPrimitiveType(ftype).ordinal(); return Wrapper.forPrimitiveType(ftype).ordinal();
else if (VerifyType.isNullReferenceConversion(Object.class, ftype)) else if (VerifyType.isNullReferenceConversion(Object.class, ftype))
@ -566,7 +566,64 @@ class DirectMethodHandle extends MethodHandle {
private static final Wrapper[] ALL_WRAPPERS = Wrapper.values(); private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) { private static Kind getFieldKind(boolean isGetter, boolean isVolatile, Wrapper wrapper) {
if (isGetter) {
if (isVolatile) {
switch (wrapper) {
case BOOLEAN: return GET_BOOLEAN_VOLATILE;
case BYTE: return GET_BYTE_VOLATILE;
case SHORT: return GET_SHORT_VOLATILE;
case CHAR: return GET_CHAR_VOLATILE;
case INT: return GET_INT_VOLATILE;
case LONG: return GET_LONG_VOLATILE;
case FLOAT: return GET_FLOAT_VOLATILE;
case DOUBLE: return GET_DOUBLE_VOLATILE;
case OBJECT: return GET_OBJECT_VOLATILE;
}
} else {
switch (wrapper) {
case BOOLEAN: return GET_BOOLEAN;
case BYTE: return GET_BYTE;
case SHORT: return GET_SHORT;
case CHAR: return GET_CHAR;
case INT: return GET_INT;
case LONG: return GET_LONG;
case FLOAT: return GET_FLOAT;
case DOUBLE: return GET_DOUBLE;
case OBJECT: return GET_OBJECT;
}
}
} else {
if (isVolatile) {
switch (wrapper) {
case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
case BYTE: return PUT_BYTE_VOLATILE;
case SHORT: return PUT_SHORT_VOLATILE;
case CHAR: return PUT_CHAR_VOLATILE;
case INT: return PUT_INT_VOLATILE;
case LONG: return PUT_LONG_VOLATILE;
case FLOAT: return PUT_FLOAT_VOLATILE;
case DOUBLE: return PUT_DOUBLE_VOLATILE;
case OBJECT: return PUT_OBJECT_VOLATILE;
}
} else {
switch (wrapper) {
case BOOLEAN: return PUT_BOOLEAN;
case BYTE: return PUT_BYTE;
case SHORT: return PUT_SHORT;
case CHAR: return PUT_CHAR;
case INT: return PUT_INT;
case LONG: return PUT_LONG;
case FLOAT: return PUT_FLOAT;
case DOUBLE: return PUT_DOUBLE;
case OBJECT: return PUT_OBJECT;
}
}
}
throw new AssertionError("Invalid arguments");
}
static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1); boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
boolean isStatic = (formOp >= AF_GETSTATIC); boolean isStatic = (formOp >= AF_GETSTATIC);
boolean needsInit = (formOp >= AF_GETSTATIC_INIT); boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
@ -576,24 +633,14 @@ class DirectMethodHandle extends MethodHandle {
assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind); assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
// getObject, putIntVolatile, etc. // getObject, putIntVolatile, etc.
StringBuilder nameBuilder = new StringBuilder(); Kind kind = getFieldKind(isGetter, isVolatile, fw);
if (isGetter) {
nameBuilder.append("get");
} else {
nameBuilder.append("put");
}
nameBuilder.append(fw.primitiveSimpleName());
nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3)));
if (isVolatile) {
nameBuilder.append("Volatile");
}
MethodType linkerType; MethodType linkerType;
if (isGetter) if (isGetter)
linkerType = MethodType.methodType(ft, Object.class, long.class); linkerType = MethodType.methodType(ft, Object.class, long.class);
else else
linkerType = MethodType.methodType(void.class, Object.class, long.class, ft); linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
MemberName linker = new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual); MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
try { try {
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class); linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
@ -620,6 +667,7 @@ class DirectMethodHandle extends MethodHandle {
final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
final int F_OFFSET = nameCursor++; // Either static offset or field offset. final int F_OFFSET = nameCursor++; // Either static offset or field offset.
final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1); final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
final int U_HOLDER = nameCursor++; // UNSAFE holder
final int INIT_BAR = (needsInit ? nameCursor++ : -1); final int INIT_BAR = (needsInit ? nameCursor++ : -1);
final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1); final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
final int LINKER_CALL = nameCursor++; final int LINKER_CALL = nameCursor++;
@ -632,7 +680,7 @@ class DirectMethodHandle extends MethodHandle {
names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]); names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
Object[] outArgs = new Object[1 + linkerType.parameterCount()]; Object[] outArgs = new Object[1 + linkerType.parameterCount()];
assert(outArgs.length == (isGetter ? 3 : 4)); assert(outArgs.length == (isGetter ? 3 : 4));
outArgs[0] = UNSAFE; outArgs[0] = names[U_HOLDER] = new Name(NF_UNSAFE);
if (isStatic) { if (isStatic) {
outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]); outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]);
outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]); outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]);
@ -650,6 +698,7 @@ class DirectMethodHandle extends MethodHandle {
for (Name n : names) assert(n != null); for (Name n : names) assert(n != null);
// add some detail to the lambdaForm debugname, // add some detail to the lambdaForm debugname,
// significant only for debugging // significant only for debugging
StringBuilder nameBuilder = new StringBuilder(kind.methodName);
if (isStatic) { if (isStatic) {
nameBuilder.append("Static"); nameBuilder.append("Static");
} else { } else {
@ -657,7 +706,12 @@ class DirectMethodHandle extends MethodHandle {
} }
if (needsCast) nameBuilder.append("Cast"); if (needsCast) nameBuilder.append("Cast");
if (needsInit) nameBuilder.append("Init"); if (needsInit) nameBuilder.append("Init");
return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT); if (needsCast || needsInit) {
// can't use the pre-generated form when casting and/or initializing
return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
} else {
return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT, kind);
}
} }
/** /**
@ -674,7 +728,8 @@ class DirectMethodHandle extends MethodHandle {
NF_staticOffset, NF_staticOffset,
NF_checkCast, NF_checkCast,
NF_allocateInstance, NF_allocateInstance,
NF_constructorMethod; NF_constructorMethod,
NF_UNSAFE;
static { static {
try { try {
NamedFunction nfs[] = { NamedFunction nfs[] = {
@ -697,7 +752,9 @@ class DirectMethodHandle extends MethodHandle {
NF_allocateInstance = new NamedFunction(DirectMethodHandle.class NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
.getDeclaredMethod("allocateInstance", Object.class)), .getDeclaredMethod("allocateInstance", Object.class)),
NF_constructorMethod = new NamedFunction(DirectMethodHandle.class NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
.getDeclaredMethod("constructorMethod", Object.class)) .getDeclaredMethod("constructorMethod", Object.class)),
NF_UNSAFE = new NamedFunction(new MemberName(MethodHandleStatics.class
.getDeclaredField("UNSAFE")))
}; };
// Each nf must be statically invocable or we get tied up in our bootstraps. // Each nf must be statically invocable or we get tied up in our bootstraps.
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs)); assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));

View File

@ -28,9 +28,11 @@ package java.lang.invoke;
import java.util.Map; import java.util.Map;
import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes; import jdk.internal.org.objectweb.asm.Opcodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import sun.invoke.util.Wrapper;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
/** /**
* Helper class to assist the GenerateJLIClassesPlugin to get access to * Helper class to assist the GenerateJLIClassesPlugin to get access to
@ -66,14 +68,38 @@ class GenerateJLIClassesHelper {
static byte[] generateDirectMethodHandleHolderClassBytes(String className, static byte[] generateDirectMethodHandleHolderClassBytes(String className,
MethodType[] methodTypes, int[] types) { MethodType[] methodTypes, int[] types) {
LambdaForm[] forms = new LambdaForm[methodTypes.length]; ArrayList<LambdaForm> forms = new ArrayList<>();
String[] names = new String[methodTypes.length]; ArrayList<String> names = new ArrayList<>();
for (int i = 0; i < forms.length; i++) { for (int i = 0; i < methodTypes.length; i++) {
forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i], LambdaForm form = DirectMethodHandle
types[i]); .makePreparedLambdaForm(methodTypes[i], types[i]);
names[i] = forms[i].kind.defaultLambdaName; forms.add(form);
names.add(form.kind.defaultLambdaName);
} }
return generateCodeBytesForLFs(className, names, forms); for (Wrapper wrapper : Wrapper.values()) {
if (wrapper == Wrapper.VOID) {
continue;
}
for (byte b = DirectMethodHandle.AF_GETFIELD; b < DirectMethodHandle.AF_LIMIT; b++) {
int ftype = DirectMethodHandle.ftypeKind(wrapper.primitiveType());
LambdaForm form = DirectMethodHandle
.makePreparedFieldLambdaForm(b, /*isVolatile*/false, ftype);
if (form.kind != LambdaForm.Kind.GENERIC) {
forms.add(form);
names.add(form.kind.defaultLambdaName);
}
// volatile
form = DirectMethodHandle
.makePreparedFieldLambdaForm(b, /*isVolatile*/true, ftype);
if (form.kind != LambdaForm.Kind.GENERIC) {
forms.add(form);
names.add(form.kind.defaultLambdaName);
}
}
}
return generateCodeBytesForLFs(className,
names.toArray(new String[0]),
forms.toArray(new LambdaForm[0]));
} }
static byte[] generateDelegatingMethodHandleHolderClassBytes(String className, static byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
@ -107,6 +133,34 @@ class GenerateJLIClassesHelper {
forms.toArray(new LambdaForm[0])); forms.toArray(new LambdaForm[0]));
} }
static byte[] generateInvokersHolderClassBytes(String className,
MethodType[] methodTypes) {
HashSet<MethodType> dedupSet = new HashSet<>();
ArrayList<LambdaForm> forms = new ArrayList<>();
ArrayList<String> names = new ArrayList<>();
int[] types = {
MethodTypeForm.LF_EX_LINKER,
MethodTypeForm.LF_EX_INVOKER,
MethodTypeForm.LF_GEN_LINKER,
MethodTypeForm.LF_GEN_INVOKER
};
for (int i = 0; i < methodTypes.length; i++) {
// generate methods representing invokers of the specified type
if (dedupSet.add(methodTypes[i])) {
for (int type : types) {
LambdaForm invokerForm = Invokers.invokeHandleForm(methodTypes[i],
/*customized*/false, type);
forms.add(invokerForm);
names.add(invokerForm.kind.defaultLambdaName);
}
}
}
return generateCodeBytesForLFs(className,
names.toArray(new String[0]),
forms.toArray(new LambdaForm[0]));
}
/* /*
* Generate customized code for a set of LambdaForms of specified types into * Generate customized code for a set of LambdaForms of specified types into
* a class with a specified name. * a class with a specified name.
@ -166,4 +220,5 @@ class GenerateJLIClassesHelper {
BoundMethodHandle.Factory.generateConcreteBMHClassBytes( BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
shortTypes, types, className)); shortTypes, types, className));
} }
} }

View File

@ -607,7 +607,10 @@ class InvokerBytecodeGenerator {
private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) { private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
MemberName member = new MemberName(holder, name, type, REF_invokeStatic); MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder); MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
if (TRACE_RESOLVE) {
System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " +
shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") );
}
return resolvedMember; return resolvedMember;
} }
@ -629,6 +632,28 @@ class InvokerBytecodeGenerator {
name = name + "_" + form.returnType().basicTypeChar(); name = name + "_" + form.returnType().basicTypeChar();
return resolveFrom(name, invokerType, LambdaForm.Holder.class); return resolveFrom(name, invokerType, LambdaForm.Holder.class);
} }
case EXACT_INVOKER: // fall-through
case EXACT_LINKER: // fall-through
case GENERIC_INVOKER: // fall-through
case GENERIC_LINKER: return resolveFrom(name, invokerType.basicType(), Invokers.Holder.class);
case GET_OBJECT: // fall-through
case GET_BOOLEAN: // fall-through
case GET_BYTE: // fall-through
case GET_CHAR: // fall-through
case GET_SHORT: // fall-through
case GET_INT: // fall-through
case GET_LONG: // fall-through
case GET_FLOAT: // fall-through
case GET_DOUBLE: // fall-through
case PUT_OBJECT: // fall-through
case PUT_BOOLEAN: // fall-through
case PUT_BYTE: // fall-through
case PUT_CHAR: // fall-through
case PUT_SHORT: // fall-through
case PUT_INT: // fall-through
case PUT_LONG: // fall-through
case PUT_FLOAT: // fall-through
case PUT_DOUBLE: // fall-through
case DIRECT_INVOKE_INTERFACE: // fall-through case DIRECT_INVOKE_INTERFACE: // fall-through
case DIRECT_INVOKE_SPECIAL: // fall-through case DIRECT_INVOKE_SPECIAL: // fall-through
case DIRECT_INVOKE_STATIC: // fall-through case DIRECT_INVOKE_STATIC: // fall-through

View File

@ -36,6 +36,7 @@ import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
import static java.lang.invoke.LambdaForm.*; import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.LambdaForm.Kind.*;
/** /**
* Construction and caching of often-used invokers. * Construction and caching of often-used invokers.
@ -254,7 +255,7 @@ class Invokers {
* @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker"); * @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker");
* 0x02 whether it is for invokeExact or generic invoke * 0x02 whether it is for invokeExact or generic invoke
*/ */
private static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) { static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) {
boolean isCached; boolean isCached;
if (!customized) { if (!customized) {
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc. mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
@ -263,12 +264,12 @@ class Invokers {
isCached = false; // maybe cache if mtype == mtype.basicType() isCached = false; // maybe cache if mtype == mtype.basicType()
} }
boolean isLinker, isGeneric; boolean isLinker, isGeneric;
String debugName; Kind kind;
switch (which) { switch (which) {
case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; debugName = "invokeExact_MT"; break; case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; kind = EXACT_LINKER; break;
case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; debugName = "exactInvoker"; break; case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; kind = EXACT_INVOKER; break;
case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; debugName = "invoke_MT"; break; case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; kind = GENERIC_LINKER; break;
case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; debugName = "invoker"; break; case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; kind = GENERIC_INVOKER; break;
default: throw new InternalError(); default: throw new InternalError();
} }
LambdaForm lform; LambdaForm lform;
@ -323,7 +324,11 @@ class Invokers {
names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]); names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
} }
names[LINKER_CALL] = new Name(outCallType, outArgs); names[LINKER_CALL] = new Name(outCallType, outArgs);
lform = new LambdaForm(debugName, INARG_LIMIT, names); if (customized) {
lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names);
} else {
lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names, kind);
}
if (isLinker) if (isLinker)
lform.compileToBytecode(); // JVM needs a real methodOop lform.compileToBytecode(); // JVM needs a real methodOop
if (isCached) if (isCached)
@ -614,4 +619,15 @@ class Invokers {
} }
} }
} }
static {
// The Holder class will contain pre-generated Invokers resolved
// speculatively using MemberName.getFactory().resolveOrNull. However, that
// doesn't initialize the class, which subtly breaks inlining etc. By forcing
// initialization of the Holder class we avoid these issues.
UNSAFE.ensureClassInitialized(Holder.class);
}
/* Placeholder class for Invokers generated ahead of time */
final class Holder {}
} }

View File

@ -275,12 +275,52 @@ class LambdaForm {
BOUND_REINVOKER("BMH.reinvoke"), BOUND_REINVOKER("BMH.reinvoke"),
REINVOKER("MH.reinvoke"), REINVOKER("MH.reinvoke"),
DELEGATE("MH.delegate"), DELEGATE("MH.delegate"),
EXACT_LINKER("MH.invokeExact_MT"),
EXACT_INVOKER("MH.exactInvoker"),
GENERIC_LINKER("MH.invoke_MT"),
GENERIC_INVOKER("MH.invoker"),
DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"), DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"),
DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"), DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"),
DIRECT_INVOKE_STATIC("DMH.invokeStatic"), DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"), DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"),
DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"), DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"),
DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"); DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"),
GET_OBJECT("getObject"),
PUT_OBJECT("putObject"),
GET_OBJECT_VOLATILE("getObjectVolatile"),
PUT_OBJECT_VOLATILE("putObjectVolatile"),
GET_INT("getInt"),
PUT_INT("putInt"),
GET_INT_VOLATILE("getIntVolatile"),
PUT_INT_VOLATILE("putIntVolatile"),
GET_BOOLEAN("getBoolean"),
PUT_BOOLEAN("putBoolean"),
GET_BOOLEAN_VOLATILE("getBooleanVolatile"),
PUT_BOOLEAN_VOLATILE("putBooleanVolatile"),
GET_BYTE("getByte"),
PUT_BYTE("putByte"),
GET_BYTE_VOLATILE("getByteVolatile"),
PUT_BYTE_VOLATILE("putByteVolatile"),
GET_CHAR("getChar"),
PUT_CHAR("putChar"),
GET_CHAR_VOLATILE("getCharVolatile"),
PUT_CHAR_VOLATILE("putCharVolatile"),
GET_SHORT("getShort"),
PUT_SHORT("putShort"),
GET_SHORT_VOLATILE("getShortVolatile"),
PUT_SHORT_VOLATILE("putShortVolatile"),
GET_LONG("getLong"),
PUT_LONG("putLong"),
GET_LONG_VOLATILE("getLongVolatile"),
PUT_LONG_VOLATILE("putLongVolatile"),
GET_FLOAT("getFloat"),
PUT_FLOAT("putFloat"),
GET_FLOAT_VOLATILE("getFloatVolatile"),
PUT_FLOAT_VOLATILE("putFloatVolatile"),
GET_DOUBLE("getDouble"),
PUT_DOUBLE("putDouble"),
GET_DOUBLE_VOLATILE("getDoubleVolatile"),
PUT_DOUBLE_VOLATILE("putDoubleVolatile");
final String defaultLambdaName; final String defaultLambdaName;
final String methodName; final String methodName;
@ -329,6 +369,10 @@ class LambdaForm {
int arity, Name[] names) { int arity, Name[] names) {
this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
} }
LambdaForm(String debugName,
int arity, Name[] names, Kind kind) {
this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, kind);
}
LambdaForm(String debugName, LambdaForm(String debugName,
int arity, Name[] names, boolean forceInline) { int arity, Name[] names, boolean forceInline) {
this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC); this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC);
@ -817,54 +861,6 @@ class LambdaForm {
} }
} }
private static void computeInitialPreparedForms() {
// Find all predefined invokers and associate them with canonical empty lambda forms.
for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) {
if (!m.isStatic() || !m.isPackage()) continue;
MethodType mt = m.getMethodType();
if (mt.parameterCount() > 0 &&
mt.parameterType(0) == MethodHandle.class &&
m.getName().startsWith("interpret_")) {
String sig = null;
assert((sig = basicTypeSignature(mt)) != null &&
m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
LambdaForm form = new LambdaForm(mt);
form.vmentry = m;
form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form);
}
}
}
// Set this false to disable use of the interpret_L methods defined in this file.
private static final boolean USE_PREDEFINED_INTERPRET_METHODS = true;
// The following are predefined exact invokers. The system must build
// a separate invoker for each distinct signature.
static Object interpret_L(MethodHandle mh) throws Throwable {
Object[] av = {mh};
String sig = null;
assert(argumentTypesMatch(sig = "L_L", av));
Object res = mh.form.interpretWithArguments(av);
assert(returnTypesMatch(sig, av, res));
return res;
}
static Object interpret_L(MethodHandle mh, Object x1) throws Throwable {
Object[] av = {mh, x1};
String sig = null;
assert(argumentTypesMatch(sig = "LL_L", av));
Object res = mh.form.interpretWithArguments(av);
assert(returnTypesMatch(sig, av, res));
return res;
}
static Object interpret_L(MethodHandle mh, Object x1, Object x2) throws Throwable {
Object[] av = {mh, x1, x2};
String sig = null;
assert(argumentTypesMatch(sig = "LLL_L", av));
Object res = mh.form.interpretWithArguments(av);
assert(returnTypesMatch(sig, av, res));
return res;
}
// The next few routines are called only from assert expressions // The next few routines are called only from assert expressions
// They verify that the built-in invokers process the correct raw data types. // They verify that the built-in invokers process the correct raw data types.
private static boolean argumentTypesMatch(String sig, Object[] av) { private static boolean argumentTypesMatch(String sig, Object[] av) {
@ -1151,113 +1147,6 @@ class LambdaForm {
return super.hashCode(); return super.hashCode();
} }
// Put the predefined NamedFunction invokers into the table.
static void initializeInvokers() {
for (MemberName m : MemberName.getFactory().getMethods(NamedFunction.class, false, null, null, null)) {
if (!m.isStatic() || !m.isPackage()) continue;
MethodType type = m.getMethodType();
if (type.equals(INVOKER_METHOD_TYPE) &&
m.getName().startsWith("invoke_")) {
String sig = m.getName().substring("invoke_".length());
int arity = LambdaForm.signatureArity(sig);
MethodType srcType = MethodType.genericMethodType(arity);
if (LambdaForm.signatureReturn(sig) == V_TYPE)
srcType = srcType.changeReturnType(void.class);
MethodTypeForm typeForm = srcType.form();
typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, DirectMethodHandle.make(m));
}
}
}
// The following are predefined NamedFunction invokers. The system must build
// a separate invoker for each distinct signature.
/** void return type invokers. */
@Hidden
static Object invoke__V(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(0, void.class, mh, a));
mh.invokeBasic();
return null;
}
@Hidden
static Object invoke_L_V(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(1, void.class, mh, a));
mh.invokeBasic(a[0]);
return null;
}
@Hidden
static Object invoke_LL_V(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(2, void.class, mh, a));
mh.invokeBasic(a[0], a[1]);
return null;
}
@Hidden
static Object invoke_LLL_V(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(3, void.class, mh, a));
mh.invokeBasic(a[0], a[1], a[2]);
return null;
}
@Hidden
static Object invoke_LLLL_V(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(4, void.class, mh, a));
mh.invokeBasic(a[0], a[1], a[2], a[3]);
return null;
}
@Hidden
static Object invoke_LLLLL_V(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(5, void.class, mh, a));
mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
return null;
}
/** Object return type invokers. */
@Hidden
static Object invoke__L(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(0, mh, a));
return mh.invokeBasic();
}
@Hidden
static Object invoke_L_L(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(1, mh, a));
return mh.invokeBasic(a[0]);
}
@Hidden
static Object invoke_LL_L(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(2, mh, a));
return mh.invokeBasic(a[0], a[1]);
}
@Hidden
static Object invoke_LLL_L(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(3, mh, a));
return mh.invokeBasic(a[0], a[1], a[2]);
}
@Hidden
static Object invoke_LLLL_L(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(4, mh, a));
return mh.invokeBasic(a[0], a[1], a[2], a[3]);
}
@Hidden
static Object invoke_LLLLL_L(MethodHandle mh, Object[] a) throws Throwable {
assert(arityCheck(5, mh, a));
return mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
}
private static boolean arityCheck(int arity, MethodHandle mh, Object[] a) {
return arityCheck(arity, Object.class, mh, a);
}
private static boolean arityCheck(int arity, Class<?> rtype, MethodHandle mh, Object[] a) {
assert(a.length == arity)
: Arrays.asList(a.length, arity);
assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype))
: Arrays.asList(mh, rtype, arity);
MemberName member = mh.internalMemberName();
if (isInvokeBasic(member)) {
assert(arity > 0);
assert(a[0] instanceof MethodHandle);
MethodHandle mh2 = (MethodHandle) a[0];
assert(mh2.type().basicType() == MethodType.genericMethodType(arity-1).changeReturnType(rtype))
: Arrays.asList(member, mh2, rtype, arity);
}
return true;
}
static final MethodType INVOKER_METHOD_TYPE = static final MethodType INVOKER_METHOD_TYPE =
MethodType.methodType(Object.class, MethodHandle.class, Object[].class); MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
@ -1920,12 +1809,7 @@ class LambdaForm {
DEBUG_NAME_COUNTERS = null; DEBUG_NAME_COUNTERS = null;
} }
// Put this last, so that previous static inits can run before.
static { static {
if (USE_PREDEFINED_INTERPRET_METHODS)
computeInitialPreparedForms();
NamedFunction.initializeInvokers();
// The Holder class will contain pre-generated forms resolved // The Holder class will contain pre-generated forms resolved
// using MemberName.getFactory(). However, that doesn't initialize the // using MemberName.getFactory(). However, that doesn't initialize the
// class, which subtly breaks inlining etc. By forcing // class, which subtly breaks inlining etc. By forcing

View File

@ -1745,6 +1745,13 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
return GenerateJLIClassesHelper return GenerateJLIClassesHelper
.generateBasicFormsClassBytes(className); .generateBasicFormsClassBytes(className);
} }
@Override
public byte[] generateInvokersHolderClassBytes(final String className,
MethodType[] methodTypes) {
return GenerateJLIClassesHelper
.generateInvokersHolderClassBytes(className, methodTypes);
}
}); });
} }

View File

@ -46,6 +46,7 @@ import java.util.Properties;
static final boolean DUMP_CLASS_FILES; static final boolean DUMP_CLASS_FILES;
static final boolean TRACE_INTERPRETER; static final boolean TRACE_INTERPRETER;
static final boolean TRACE_METHOD_LINKAGE; static final boolean TRACE_METHOD_LINKAGE;
static final boolean TRACE_RESOLVE;
static final int COMPILE_THRESHOLD; static final int COMPILE_THRESHOLD;
static final boolean LOG_LF_COMPILATION_FAILURE; static final boolean LOG_LF_COMPILATION_FAILURE;
static final int DONT_INLINE_THRESHOLD; static final int DONT_INLINE_THRESHOLD;
@ -65,6 +66,8 @@ import java.util.Properties;
props.getProperty("java.lang.invoke.MethodHandle.TRACE_INTERPRETER")); props.getProperty("java.lang.invoke.MethodHandle.TRACE_INTERPRETER"));
TRACE_METHOD_LINKAGE = Boolean.parseBoolean( TRACE_METHOD_LINKAGE = Boolean.parseBoolean(
props.getProperty("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE")); props.getProperty("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"));
TRACE_RESOLVE = Boolean.parseBoolean(
props.getProperty("java.lang.invoke.MethodHandle.TRACE_RESOLVE"));
COMPILE_THRESHOLD = Integer.parseInt( COMPILE_THRESHOLD = Integer.parseInt(
props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0")); props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0"));
LOG_LF_COMPILATION_FAILURE = Boolean.parseBoolean( LOG_LF_COMPILATION_FAILURE = Boolean.parseBoolean(

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -233,7 +233,7 @@ public final class HttpCookie implements Cloneable {
// if not specify max-age, this cookie should be // if not specify max-age, this cookie should be
// discarded when user agent is to be closed, but // discarded when user agent is to be closed, but
// it is not expired. // it is not expired.
if (maxAge == MAX_AGE_UNSPECIFIED) return false; if (maxAge < 0) return false;
long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000; long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000;
if (deltaSecond > maxAge) if (deltaSecond > maxAge)
@ -952,7 +952,8 @@ public final class HttpCookie implements Cloneable {
String attrName, String attrName,
String attrValue) { String attrValue) {
if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED) { if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED) {
cookie.setMaxAge(cookie.expiryDate2DeltaSeconds(attrValue)); long delta = cookie.expiryDate2DeltaSeconds(attrValue);
cookie.setMaxAge(delta > 0 ? delta : 0);
} }
} }
}); });

View File

@ -150,10 +150,12 @@ public final class Duration
/** /**
* The pattern for parsing. * The pattern for parsing.
*/ */
private static final Pattern PATTERN = private static class Lazy {
static final Pattern PATTERN =
Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" + Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" +
"(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?", "(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?",
Pattern.CASE_INSENSITIVE); Pattern.CASE_INSENSITIVE);
}
/** /**
* The number of seconds in the duration. * The number of seconds in the duration.
@ -387,7 +389,7 @@ public final class Duration
*/ */
public static Duration parse(CharSequence text) { public static Duration parse(CharSequence text) {
Objects.requireNonNull(text, "text"); Objects.requireNonNull(text, "text");
Matcher matcher = PATTERN.matcher(text); Matcher matcher = Lazy.PATTERN.matcher(text);
if (matcher.matches()) { if (matcher.matches()) {
// check for letter T but no time sections // check for letter T but no time sections
if (!charMatch(text, matcher.start(3), matcher.end(3), 'T')) { if (!charMatch(text, matcher.start(3), matcher.end(3), 'T')) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -375,15 +375,15 @@ public final class ZoneOffset
} else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) { } else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
throw new DateTimeException("Zone offset minutes and seconds must have the same sign"); throw new DateTimeException("Zone offset minutes and seconds must have the same sign");
} }
if (Math.abs(minutes) > 59) { if (minutes < -59 || minutes > 59) {
throw new DateTimeException("Zone offset minutes not in valid range: abs(value) " + throw new DateTimeException("Zone offset minutes not in valid range: value " +
Math.abs(minutes) + " is not in the range 0 to 59"); minutes + " is not in the range -59 to 59");
} }
if (Math.abs(seconds) > 59) { if (seconds < -59 || seconds > 59) {
throw new DateTimeException("Zone offset seconds not in valid range: abs(value) " + throw new DateTimeException("Zone offset seconds not in valid range: value " +
Math.abs(seconds) + " is not in the range 0 to 59"); seconds + " is not in the range -59 to 59");
} }
if (Math.abs(hours) == 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) { if (Math.abs(hours) == 18 && (minutes | seconds) != 0) {
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00"); throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
} }
} }
@ -411,7 +411,7 @@ public final class ZoneOffset
* @throws DateTimeException if the offset is not in the required range * @throws DateTimeException if the offset is not in the required range
*/ */
public static ZoneOffset ofTotalSeconds(int totalSeconds) { public static ZoneOffset ofTotalSeconds(int totalSeconds) {
if (Math.abs(totalSeconds) > MAX_SECONDS) { if (totalSeconds < -MAX_SECONDS || totalSeconds > MAX_SECONDS) {
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00"); throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
} }
if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) { if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) {
@ -696,11 +696,12 @@ public final class ZoneOffset
* The comparison is "consistent with equals", as defined by {@link Comparable}. * The comparison is "consistent with equals", as defined by {@link Comparable}.
* *
* @param other the other date to compare to, not null * @param other the other date to compare to, not null
* @return the comparator value, negative if less, postive if greater * @return the comparator value, negative if less, positive if greater
* @throws NullPointerException if {@code other} is null * @throws NullPointerException if {@code other} is null
*/ */
@Override @Override
public int compareTo(ZoneOffset other) { public int compareTo(ZoneOffset other) {
// abs(totalSeconds) <= MAX_SECONDS, so no overflow can happen here
return other.totalSeconds - totalSeconds; return other.totalSeconds - totalSeconds;
} }

View File

@ -4566,7 +4566,10 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
boolean modified = false; boolean modified = false;
// Use (c instanceof Set) as a hint that lookup in c is as // Use (c instanceof Set) as a hint that lookup in c is as
// efficient as this view // efficient as this view
if (c instanceof Set<?> && c.size() > map.table.length) { Node<K,V>[] t;
if ((t = map.table) == null) {
return false;
} else if (c instanceof Set<?> && c.size() > t.length) {
for (Iterator<?> it = iterator(); it.hasNext(); ) { for (Iterator<?> it = iterator(); it.hasNext(); ) {
if (c.contains(it.next())) { if (c.contains(it.next())) {
it.remove(); it.remove();

View File

@ -353,7 +353,7 @@ class JarFile extends ZipFile {
if (isMultiRelease) { if (isMultiRelease) {
return true; return true;
} }
if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) { if (MULTI_RELEASE_ENABLED) {
try { try {
checkForSpecialAttributes(); checkForSpecialAttributes();
} catch (IOException io) { } catch (IOException io) {
@ -644,7 +644,7 @@ class JarFile extends ZipFile {
return signers == null ? null : signers.clone(); return signers == null ? null : signers.clone();
} }
JarFileEntry realEntry() { JarFileEntry realEntry() {
if (isMultiRelease()) { if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) {
String entryName = super.getName(); String entryName = super.getName();
return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this); return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this);
} }
@ -960,7 +960,7 @@ class JarFile extends ZipFile {
hasClassPathAttribute = match(CLASSPATH_CHARS, b, hasClassPathAttribute = match(CLASSPATH_CHARS, b,
CLASSPATH_LASTOCC) != -1; CLASSPATH_LASTOCC) != -1;
// is this a multi-release jar file // is this a multi-release jar file
if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) { if (MULTI_RELEASE_ENABLED) {
int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC); int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC);
if (i != -1) { if (i != -1) {
i += MULTIRELEASE_CHARS.length; i += MULTIRELEASE_CHARS.length;

View File

@ -29,6 +29,7 @@ import java.util.*;
import java.util.jar.*; import java.util.jar.*;
import java.io.*; import java.io.*;
import java.net.URL; import java.net.URL;
import java.nio.file.*;
import java.security.*; import java.security.*;
import java.security.Provider.Service; import java.security.Provider.Service;
@ -206,7 +207,7 @@ final class JceSecurity {
static { static {
try { try {
NULL_URL = new URL("http://null.sun.com/"); NULL_URL = new URL("http://null.oracle.com/");
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -243,83 +244,94 @@ final class JceSecurity {
} }
} }
// This is called from within an doPrivileged block.
private static void setupJurisdictionPolicies() throws Exception { private static void setupJurisdictionPolicies() throws Exception {
String javaHomeDir = System.getProperty("java.home");
String sep = File.separator;
String pathToPolicyJar = javaHomeDir + sep + "lib" + sep +
"security" + sep;
File exportJar = new File(pathToPolicyJar, "US_export_policy.jar"); // Sanity check the crypto.policy Security property. Single
File importJar = new File(pathToPolicyJar, "local_policy.jar"); // directory entry, no pseudo-directories (".", "..", leading/trailing
// path separators). normalize()/getParent() will help later.
String cryptoPolicyProperty = Security.getProperty("crypto.policy");
Path cpPath = Paths.get(cryptoPolicyProperty);
if (!exportJar.exists() || !importJar.exists()) { if ((cryptoPolicyProperty == null) ||
throw new SecurityException (cpPath.getNameCount() != 1) ||
("Cannot locate policy or framework files!"); (cpPath.compareTo(cpPath.getFileName()) != 0)) {
throw new SecurityException(
"Invalid policy directory name format: " +
cryptoPolicyProperty);
} }
// Read jurisdiction policies. // Prepend java.home to get the full path. normalize() in
CryptoPermissions defaultExport = new CryptoPermissions(); // case an extra "." or ".." snuck in somehow.
CryptoPermissions exemptExport = new CryptoPermissions(); String javaHomeProperty = System.getProperty("java.home");
loadPolicies(exportJar, defaultExport, exemptExport); Path javaHomePolicyPath = Paths.get(javaHomeProperty, "conf",
"security", "policy").normalize();
Path cryptoPolicyPath = Paths.get(javaHomeProperty, "conf", "security",
"policy", cryptoPolicyProperty).normalize();
CryptoPermissions defaultImport = new CryptoPermissions(); if (cryptoPolicyPath.getParent().compareTo(javaHomePolicyPath) != 0) {
CryptoPermissions exemptImport = new CryptoPermissions(); throw new SecurityException(
loadPolicies(importJar, defaultImport, exemptImport); "Invalid cryptographic jurisdiction policy directory path: " +
cryptoPolicyProperty);
// Merge the export and import policies for default applications.
if (defaultExport.isEmpty() || defaultImport.isEmpty()) {
throw new SecurityException("Missing mandatory jurisdiction " +
"policy files");
} }
defaultPolicy = defaultExport.getMinimum(defaultImport);
// Merge the export and import policies for exempt applications. if (!Files.isDirectory(cryptoPolicyPath)
if (exemptExport.isEmpty()) { || !Files.isReadable(cryptoPolicyPath)) {
exemptPolicy = exemptImport.isEmpty() ? null : exemptImport; throw new SecurityException(
} else { "Can't read cryptographic policy directory: " +
exemptPolicy = exemptExport.getMinimum(exemptImport); cryptoPolicyProperty);
} }
}
/** try (DirectoryStream<Path> stream = Files.newDirectoryStream(
* Load the policies from the specified file. Also checks that the cryptoPolicyPath, "{default,exempt}_*.policy")) {
* policies are correctly signed. for (Path entry : stream) {
*/ try (InputStream is = new BufferedInputStream(
private static void loadPolicies(File jarPathName, Files.newInputStream(entry))) {
CryptoPermissions defaultPolicy, String filename = entry.getFileName().toString();
CryptoPermissions exemptPolicy)
throws Exception {
JarFile jf = new JarFile(jarPathName); CryptoPermissions tmpPerms = new CryptoPermissions();
tmpPerms.load(is);
Enumeration<JarEntry> entries = jf.entries(); if (filename.startsWith("default_")) {
while (entries.hasMoreElements()) { // Did we find a default perms?
JarEntry je = entries.nextElement(); defaultPolicy = ((defaultPolicy == null) ? tmpPerms :
InputStream is = null; defaultPolicy.getMinimum(tmpPerms));
try { } else if (filename.startsWith("exempt_")) {
if (je.getName().startsWith("default_")) { // Did we find a exempt perms?
is = jf.getInputStream(je); exemptPolicy = ((exemptPolicy == null) ? tmpPerms :
defaultPolicy.load(is); exemptPolicy.getMinimum(tmpPerms));
} else if (je.getName().startsWith("exempt_")) { } else {
is = jf.getInputStream(je); // This should never happen. newDirectoryStream
exemptPolicy.load(is); // should only throw return "{default,exempt}_*.policy"
} else { throw new SecurityException(
continue; "Unexpected jurisdiction policy files in : " +
} cryptoPolicyProperty);
} finally { }
if (is != null) { } catch (Exception e) {
is.close(); throw new SecurityException(
"Couldn't parse jurisdiction policy files in: " +
cryptoPolicyProperty);
} }
} }
} catch (DirectoryIteratorException ex) {
// Enforce the signer restraint, i.e. signer of JCE framework // I/O error encountered during the iteration,
// jar should also be the signer of the two jurisdiction policy // the cause is an IOException
// jar files. throw new SecurityException(
ProviderVerifier.verifyPolicySigned(je.getCertificates()); "Couldn't iterate through the jurisdiction policy files: " +
cryptoPolicyProperty);
}
// Must have a default policy
if ((defaultPolicy == null) || defaultPolicy.isEmpty()) {
throw new SecurityException(
"Missing mandatory jurisdiction policy files: " +
cryptoPolicyProperty);
}
// If there was an empty exempt policy file, ignore it.
if ((exemptPolicy != null) && exemptPolicy.isEmpty()) {
exemptPolicy = null;
} }
// Close and nullify the JarFile reference to help GC.
jf.close();
jf = null;
} }
static CryptoPermissions getDefaultPolicy() { static CryptoPermissions getDefaultPolicy() {

View File

@ -47,8 +47,8 @@ final class JrtDirectoryStream implements DirectoryStream<Path> {
private final JrtPath dir; private final JrtPath dir;
private final DirectoryStream.Filter<? super Path> filter; private final DirectoryStream.Filter<? super Path> filter;
private volatile boolean isClosed; private boolean isClosed;
private volatile Iterator<Path> itr; private Iterator<Path> itr;
JrtDirectoryStream(JrtPath dir, JrtDirectoryStream(JrtPath dir,
DirectoryStream.Filter<? super java.nio.file.Path> filter) DirectoryStream.Filter<? super java.nio.file.Path> filter)
@ -73,24 +73,22 @@ final class JrtDirectoryStream implements DirectoryStream<Path> {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
return new Iterator<Path>() { return new Iterator<Path>() {
private Path next;
@Override @Override
public synchronized boolean hasNext() { public boolean hasNext() {
if (isClosed) synchronized (JrtDirectoryStream.this) {
return false; if (isClosed)
return itr.hasNext(); return false;
return itr.hasNext();
}
} }
@Override @Override
public synchronized Path next() { public Path next() {
if (isClosed) synchronized (JrtDirectoryStream.this) {
throw new NoSuchElementException(); if (isClosed)
return itr.next(); throw new NoSuchElementException();
} return itr.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
} }
}; };
} }

View File

@ -119,9 +119,7 @@ class JrtFileSystem extends FileSystem {
@Override @Override
public Iterable<Path> getRootDirectories() { public Iterable<Path> getRootDirectories() {
ArrayList<Path> dirs = new ArrayList<>(); return Collections.singleton(getRootPath());
dirs.add(getRootPath());
return dirs;
} }
@Override @Override
@ -159,9 +157,7 @@ class JrtFileSystem extends FileSystem {
@Override @Override
public final Iterable<FileStore> getFileStores() { public final Iterable<FileStore> getFileStores() {
ArrayList<FileStore> list = new ArrayList<>(1); return Collections.singleton(getFileStore(getRootPath()));
list.add(getFileStore(getRootPath()));
return list;
} }
private static final Set<String> supportedFileAttributeViews private static final Set<String> supportedFileAttributeViews

View File

@ -46,7 +46,7 @@ public interface JavaLangInvokeAccess {
boolean isNative(Object mname); boolean isNative(Object mname);
/** /**
* Returns a {@code byte[]} containing the bytecode for a class implementing * Returns a {@code byte[]} representation of a class implementing
* DirectMethodHandle of each pairwise combination of {@code MethodType} and * DirectMethodHandle of each pairwise combination of {@code MethodType} and
* an {@code int} representing method type. Used by * an {@code int} representing method type. Used by
* GenerateJLIClassesPlugin to generate such a class during the jlink phase. * GenerateJLIClassesPlugin to generate such a class during the jlink phase.
@ -55,7 +55,7 @@ public interface JavaLangInvokeAccess {
MethodType[] methodTypes, int[] types); MethodType[] methodTypes, int[] types);
/** /**
* Returns a {@code byte[]} containing the bytecode for a class implementing * Returns a {@code byte[]} representation of a class implementing
* DelegatingMethodHandles of each {@code MethodType} kind in the * DelegatingMethodHandles of each {@code MethodType} kind in the
* {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to * {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to
* generate such a class during the jlink phase. * generate such a class during the jlink phase.
@ -64,7 +64,7 @@ public interface JavaLangInvokeAccess {
MethodType[] methodTypes); MethodType[] methodTypes);
/** /**
* Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle * Returns a {@code byte[]} representation of {@code BoundMethodHandle}
* species class implementing the signature defined by {@code types}. Used * species class implementing the signature defined by {@code types}. Used
* by GenerateBMHClassesPlugin to enable generation of such classes during * by GenerateBMHClassesPlugin to enable generation of such classes during
* the jlink phase. Should do some added validation since this string may be * the jlink phase. Should do some added validation since this string may be
@ -74,8 +74,15 @@ public interface JavaLangInvokeAccess {
final String types); final String types);
/** /**
* Returns a {@code byte[]} containing the bytecode for a class implementing * Returns a {@code byte[]} representation of a class implementing
* the zero and identity forms of all {@code LambdaForm.BasicType}s. * the zero and identity forms of all {@code LambdaForm.BasicType}s.
*/ */
byte[] generateBasicFormsClassBytes(final String className); byte[] generateBasicFormsClassBytes(final String className);
/**
* Returns a {@code byte[]} representation of a class implementing
* the invoker forms for the set of supplied {@code methodTypes}.
*/
byte[] generateInvokersHolderClassBytes(String className,
MethodType[] methodTypes);
} }

View File

@ -253,7 +253,8 @@ public final class RSAPadding {
public byte[] pad(byte[] data) throws BadPaddingException { public byte[] pad(byte[] data) throws BadPaddingException {
if (data.length > maxDataSize) { if (data.length > maxDataSize) {
throw new BadPaddingException("Data must be shorter than " throw new BadPaddingException("Data must be shorter than "
+ (maxDataSize + 1) + " bytes"); + (maxDataSize + 1) + " bytes but received "
+ data.length + " bytes.");
} }
switch (type) { switch (type) {
case PAD_NONE: case PAD_NONE:
@ -281,7 +282,9 @@ public final class RSAPadding {
*/ */
public byte[] unpad(byte[] padded) throws BadPaddingException { public byte[] unpad(byte[] padded) throws BadPaddingException {
if (padded.length != paddedSize) { if (padded.length != paddedSize) {
throw new BadPaddingException("Decryption error"); throw new BadPaddingException("Decryption error." +
"The padded array length (" + padded.length +
") is not the specified padded size (" + paddedSize + ")");
} }
switch (type) { switch (type) {
case PAD_NONE: case PAD_NONE:

View File

@ -493,7 +493,9 @@ final class CipherBox {
if (protocolVersion.useTLS11PlusSpec()) { if (protocolVersion.useTLS11PlusSpec()) {
if (newLen < blockSize) { if (newLen < blockSize) {
throw new BadPaddingException("invalid explicit IV"); throw new BadPaddingException("The length after " +
"padding removal (" + newLen + ") should be larger " +
"than <" + blockSize + "> since explicit IV used");
} }
} }
} }
@ -504,7 +506,6 @@ final class CipherBox {
} }
} }
/* /*
* Decrypts a block of data, returning the size of the * Decrypts a block of data, returning the size of the
* resulting block if padding was required. position and limit * resulting block if padding was required. position and limit
@ -575,7 +576,9 @@ final class CipherBox {
// check the explicit IV of TLS v1.1 or later // check the explicit IV of TLS v1.1 or later
if (protocolVersion.useTLS11PlusSpec()) { if (protocolVersion.useTLS11PlusSpec()) {
if (newLen < blockSize) { if (newLen < blockSize) {
throw new BadPaddingException("invalid explicit IV"); throw new BadPaddingException("The length after " +
"padding removal (" + newLen + ") should be larger " +
"than <" + blockSize + "> since explicit IV used");
} }
// reset the position to the end of the decrypted data // reset the position to the end of the decrypted data
@ -756,7 +759,9 @@ final class CipherBox {
// so accept that as well // so accept that as well
// v3 does not require any particular value for the other bytes // v3 does not require any particular value for the other bytes
if (padLen > blockSize) { if (padLen > blockSize) {
throw new BadPaddingException("Invalid SSLv3 padding"); throw new BadPaddingException("Padding length (" +
padLen + ") of SSLv3 message should not be bigger " +
"than the block size (" + blockSize + ")");
} }
} }
return newLen; return newLen;
@ -802,7 +807,9 @@ final class CipherBox {
// so accept that as well // so accept that as well
// v3 does not require any particular value for the other bytes // v3 does not require any particular value for the other bytes
if (padLen > blockSize) { if (padLen > blockSize) {
throw new BadPaddingException("Invalid SSLv3 padding"); throw new BadPaddingException("Padding length (" +
padLen + ") of SSLv3 message should not be bigger " +
"than the block size (" + blockSize + ")");
} }
} }
@ -925,7 +932,10 @@ final class CipherBox {
case AEAD_CIPHER: case AEAD_CIPHER:
if (bb.remaining() < (recordIvSize + tagSize)) { if (bb.remaining() < (recordIvSize + tagSize)) {
throw new BadPaddingException( throw new BadPaddingException(
"invalid AEAD cipher fragment"); "Insufficient buffer remaining for AEAD cipher " +
"fragment (" + bb.remaining() + "). Needs to be " +
"more than or equal to IV size (" + recordIvSize +
") + tag size (" + tagSize + ")");
} }
// initialize the AEAD cipher for the unique IV // initialize the AEAD cipher for the unique IV

View File

@ -27,15 +27,8 @@ package sun.util.calendar;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.lang.ref.SoftReference;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SimpleTimeZone; import java.util.SimpleTimeZone;
import java.util.TimeZone; import java.util.TimeZone;
@ -80,8 +73,6 @@ public class ZoneInfo extends TimeZone {
private static final long ABBR_MASK = 0xf00L; private static final long ABBR_MASK = 0xf00L;
private static final int TRANSITION_NSHIFT = 12; private static final int TRANSITION_NSHIFT = 12;
private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar();
/** /**
* The raw GMT offset in milliseconds between this zone and GMT. * The raw GMT offset in milliseconds between this zone and GMT.
* Negative offsets are to the west of Greenwich. To obtain local * Negative offsets are to the west of Greenwich. To obtain local
@ -379,6 +370,7 @@ public class ZoneInfo extends TimeZone {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
Gregorian gcal = CalendarSystem.getGregorianCalendar();
CalendarDate date = gcal.newCalendarDate(null); CalendarDate date = gcal.newCalendarDate(null);
date.setDate(year, month + 1, day); date.setDate(year, month + 1, day);
if (gcal.validate(date) == false) { if (gcal.validate(date) == false) {

View File

@ -490,7 +490,7 @@ networkaddress.cache.negative.ttl=10
# property is set then those two properties are ignored. # property is set then those two properties are ignored.
# #
# Example, # Example,
# ocsp.responderCertSubjectName="CN=OCSP Responder, O=XYZ Corp" # ocsp.responderCertSubjectName=CN=OCSP Responder, O=XYZ Corp
# #
# Issuer name of the OCSP responder's certificate # Issuer name of the OCSP responder's certificate
@ -505,7 +505,7 @@ networkaddress.cache.negative.ttl=10
# property is ignored. # property is ignored.
# #
# Example, # Example,
# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp" # ocsp.responderCertIssuerName=CN=Enterprise CA, O=XYZ Corp
# #
# Serial number of the OCSP responder's certificate # Serial number of the OCSP responder's certificate
@ -803,3 +803,94 @@ jdk.tls.legacyAlgorithms= \
# E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \
# EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \
# FFFFFFFF FFFFFFFF, 2} # FFFFFFFF FFFFFFFF, 2}
# Cryptographic Jurisdiction Policy defaults
#
# Due to the import control restrictions of some countries, the default
# JCE policy files allow for strong but "limited" cryptographic key
# lengths to be used. If your country's cryptographic regulations allow,
# the "unlimited" strength policy files can be used instead, which contain
# no restrictions on cryptographic strengths.
#
# If your country has restrictions that don't fit either "limited" or
# "unlimited", an appropriate set of policy files should be created and
# configured before using this distribution. The jurisdiction policy file
# configuration must reflect the cryptographic restrictions appropriate
# for your country.
#
# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY
# TO DETERMINE THE EXACT REQUIREMENTS.
#
# The policy files are flat text files organized into subdirectories of
# <java-home>/conf/security/policy. Each directory contains a complete
# set of policy files.
#
# The "crypto.policy" Security property controls the directory selection,
# and thus the effective cryptographic policy.
#
# The default set of directories is:
#
# limited | unlimited
#
# however other directories can be created and configured.
#
# Within a directory, the effective policy is the combined minimum
# permissions of the grant statements in the file(s) with the filename
# pattern "default_*.policy". At least one grant is required. For
# example:
#
# limited = Export (all) + Import (limited) = Limited
# unlimited = Export (all) + Import (all) = Unlimited
#
# The effective exemption policy is the combined minimum permissions
# of the grant statements in the file(s) with the filename pattern
# "exempt_*.policy". Exemption grants are optional.
#
# limited = grants exemption permissions, by which the
# effective policy can be circumvented.
# e.g. KeyRecovery/Escrow/Weakening.
#
# Please see the JCA documentation for additional information on these
# files and formats.
crypto.policy=crypto.policydir-tbd
#
# The policy for the XML Signature secure validation mode. The mode is
# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to
# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method,
# or by running the code with a SecurityManager.
#
# Policy:
# Constraint {"," Constraint }
# Constraint:
# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint |
# ReferenceUriSchemeConstraint | OtherConstraint
# AlgConstraint
# "disallowAlg" Uri
# MaxTransformsConstraint:
# "maxTransforms" Integer
# MaxReferencesConstraint:
# "maxReferences" Integer
# ReferenceUriSchemeConstraint:
# "disallowReferenceUriSchemes" String { String }
# OtherConstraint:
# "noDuplicateIds" | "noRetrievalMethodLoops"
#
# For AlgConstraint, Uri is the algorithm URI String that is not allowed.
# See the XML Signature Recommendation for more information on algorithm
# URI Identifiers. If the MaxTransformsConstraint or MaxReferencesConstraint is
# specified more than once, only the last entry is enforced.
#
# Note: This property is currently used by the JDK Reference implementation. It
# is not guaranteed to be examined and used by other implementations.
#
jdk.xml.dsig.secureValidationPolicy=\
disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\
disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\
disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\
disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\
maxTransforms 5,\
maxReferences 30,\
disallowReferenceUriSchemes file http https,\
noDuplicateIds,\
noRetrievalMethodLoops

View 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.

View File

@ -1,4 +1,5 @@
// Manufacturing policy file. // Default US Export policy file.
grant { grant {
// There is no restriction to any algorithms. // There is no restriction to any algorithms.
permission javax.crypto.CryptoAllPermission; permission javax.crypto.CryptoAllPermission;

View File

@ -1,5 +1,5 @@
// Some countries have import limits on crypto strength. So this file // Some countries have import limits on crypto strength, but may allow for
// will be useful. // these exemptions if the exemption mechanism is used.
grant { grant {
// There is no restriction to any algorithms if KeyRecovery is enforced. // There is no restriction to any algorithms if KeyRecovery is enforced.

View File

@ -0,0 +1,6 @@
// Default US Export policy file.
grant {
// There is no restriction to any algorithms.
permission javax.crypto.CryptoAllPermission;
};

View File

@ -1,4 +1,5 @@
// Country-specific policy file for countries with no limits on crypto strength. // Country-specific policy file for countries with no limits on crypto strength.
grant { grant {
// There is no restriction to any algorithms. // There is no restriction to any algorithms.
permission javax.crypto.CryptoAllPermission; permission javax.crypto.CryptoAllPermission;

View File

@ -72,6 +72,8 @@ grant codeBase "jrt:/java.xml.crypto" {
"removeProviderProperty.XMLDSig"; "removeProviderProperty.XMLDSig";
permission java.security.SecurityPermission permission java.security.SecurityPermission
"com.sun.org.apache.xml.internal.security.register"; "com.sun.org.apache.xml.internal.security.register";
permission java.security.SecurityPermission
"getProperty.jdk.xml.dsig.secureValidationPolicy";
}; };
grant codeBase "jrt:/java.xml.ws" { grant codeBase "jrt:/java.xml.ws" {

View File

@ -252,6 +252,21 @@ class UnixPath implements Path {
return new UnixPath(getFileSystem(), new byte[0]); return new UnixPath(getFileSystem(), new byte[0]);
} }
// return true if this path has "." or ".."
private boolean hasDotOrDotDot() {
int n = getNameCount();
for (int i=0; i<n; i++) {
byte[] bytes = getName(i).path;
if ((bytes.length == 1 && bytes[0] == '.'))
return true;
if ((bytes.length == 2 && bytes[0] == '.') && bytes[1] == '.') {
return true;
}
}
return false;
}
@Override @Override
public UnixFileSystem getFileSystem() { public UnixFileSystem getFileSystem() {
return fs; return fs;
@ -405,80 +420,94 @@ class UnixPath implements Path {
@Override @Override
public UnixPath relativize(Path obj) { public UnixPath relativize(Path obj) {
UnixPath other = toUnixPath(obj); UnixPath child = toUnixPath(obj);
if (other.equals(this)) if (child.equals(this))
return emptyPath(); return emptyPath();
// can only relativize paths of the same type // can only relativize paths of the same type
if (this.isAbsolute() != other.isAbsolute()) if (this.isAbsolute() != child.isAbsolute())
throw new IllegalArgumentException("'other' is different type of Path"); throw new IllegalArgumentException("'other' is different type of Path");
// this path is the empty path // this path is the empty path
if (this.isEmpty()) if (this.isEmpty())
return other; return child;
int bn = this.getNameCount(); UnixPath base = this;
int cn = other.getNameCount(); if (base.hasDotOrDotDot() || child.hasDotOrDotDot()) {
base = base.normalize();
child = child.normalize();
}
int baseCount = base.getNameCount();
int childCount = child.getNameCount();
// skip matching names // skip matching names
int n = (bn > cn) ? cn : bn; int n = Math.min(baseCount, childCount);
int i = 0; int i = 0;
while (i < n) { while (i < n) {
if (!this.getName(i).equals(other.getName(i))) if (!base.getName(i).equals(child.getName(i)))
break; break;
i++; i++;
} }
int dotdots = bn - i; // remaining elements in child
if (i < cn) { UnixPath childRemaining;
// remaining name components in other boolean isChildEmpty;
UnixPath remainder = other.subpath(i, cn); if (i == childCount) {
if (dotdots == 0) childRemaining = emptyPath();
return remainder; isChildEmpty = true;
// other is the empty path
boolean isOtherEmpty = other.isEmpty();
// result is a "../" for each remaining name in base
// followed by the remaining names in other. If the remainder is
// the empty path then we don't add the final trailing slash.
int len = dotdots*3 + remainder.path.length;
if (isOtherEmpty) {
assert remainder.isEmpty();
len--;
}
byte[] result = new byte[len];
int pos = 0;
while (dotdots > 0) {
result[pos++] = (byte)'.';
result[pos++] = (byte)'.';
if (isOtherEmpty) {
if (dotdots > 1) result[pos++] = (byte)'/';
} else {
result[pos++] = (byte)'/';
}
dotdots--;
}
System.arraycopy(remainder.path, 0, result, pos, remainder.path.length);
return new UnixPath(getFileSystem(), result);
} else { } else {
// no remaining names in other so result is simply a sequence of ".." childRemaining = child.subpath(i, childCount);
byte[] result = new byte[dotdots*3 - 1]; isChildEmpty = childRemaining.isEmpty();
int pos = 0;
while (dotdots > 0) {
result[pos++] = (byte)'.';
result[pos++] = (byte)'.';
// no tailing slash at the end
if (dotdots > 1)
result[pos++] = (byte)'/';
dotdots--;
}
return new UnixPath(getFileSystem(), result);
} }
// matched all of base
if (i == baseCount) {
return childRemaining;
}
// the remainder of base cannot contain ".."
UnixPath baseRemaining = base.subpath(i, baseCount);
if (baseRemaining.hasDotOrDotDot()) {
throw new IllegalArgumentException("Unable to compute relative "
+ " path from " + this + " to " + obj);
}
if (baseRemaining.isEmpty())
return childRemaining;
// number of ".." needed
int dotdots = baseRemaining.getNameCount();
if (dotdots == 0) {
return childRemaining;
}
// result is a "../" for each remaining name in base followed by the
// remaining names in child. If the remainder is the empty path
// then we don't add the final trailing slash.
int len = dotdots*3 + childRemaining.path.length;
if (isChildEmpty) {
assert childRemaining.isEmpty();
len--;
}
byte[] result = new byte[len];
int pos = 0;
while (dotdots > 0) {
result[pos++] = (byte)'.';
result[pos++] = (byte)'.';
if (isChildEmpty) {
if (dotdots > 1) result[pos++] = (byte)'/';
} else {
result[pos++] = (byte)'/';
}
dotdots--;
}
System.arraycopy(childRemaining.path,0, result, pos,
childRemaining.path.length);
return new UnixPath(getFileSystem(), result);
} }
@Override @Override
public Path normalize() { public UnixPath normalize() {
final int count = getNameCount(); final int count = getNameCount();
if (count == 0 || isEmpty()) if (count == 0 || isEmpty())
return this; return this;

View File

@ -375,57 +375,108 @@ class WindowsPath implements Path {
return (WindowsPath)path; return (WindowsPath)path;
} }
// return true if this path has "." or ".."
private boolean hasDotOrDotDot() {
int n = getNameCount();
for (int i=0; i<n; i++) {
String name = elementAsString(i);
if (name.length() == 1 && name.charAt(0) == '.')
return true;
if (name.length() == 2
&& name.charAt(0) == '.' && name.charAt(1) == '.')
return true;
}
return false;
}
@Override @Override
public WindowsPath relativize(Path obj) { public WindowsPath relativize(Path obj) {
WindowsPath other = toWindowsPath(obj); WindowsPath child = toWindowsPath(obj);
if (this.equals(other)) if (this.equals(child))
return emptyPath(); return emptyPath();
// can only relativize paths of the same type // can only relativize paths of the same type
if (this.type != other.type) if (this.type != child.type)
throw new IllegalArgumentException("'other' is different type of Path"); throw new IllegalArgumentException("'other' is different type of Path");
// can only relativize paths if root component matches // can only relativize paths if root component matches
if (!this.root.equalsIgnoreCase(other.root)) if (!this.root.equalsIgnoreCase(child.root))
throw new IllegalArgumentException("'other' has different root"); throw new IllegalArgumentException("'other' has different root");
// this path is the empty path // this path is the empty path
if (this.isEmpty()) if (this.isEmpty())
return other; return child;
int bn = this.getNameCount();
int cn = other.getNameCount(); WindowsPath base = this;
if (base.hasDotOrDotDot() || child.hasDotOrDotDot()) {
base = base.normalize();
child = child.normalize();
}
int baseCount = base.getNameCount();
int childCount = child.getNameCount();
// skip matching names // skip matching names
int n = (bn > cn) ? cn : bn; int n = Math.min(baseCount, childCount);
int i = 0; int i = 0;
while (i < n) { while (i < n) {
if (!this.getName(i).equals(other.getName(i))) if (!base.getName(i).equals(child.getName(i)))
break; break;
i++; i++;
} }
// append ..\ for remaining names in the base // remaining elements in child
WindowsPath childRemaining;
boolean isChildEmpty;
if (i == childCount) {
childRemaining = emptyPath();
isChildEmpty = true;
} else {
childRemaining = child.subpath(i, childCount);
isChildEmpty = childRemaining.isEmpty();
}
// matched all of base
if (i == baseCount) {
return childRemaining;
}
// the remainder of base cannot contain ".."
WindowsPath baseRemaining = base.subpath(i, baseCount);
if (baseRemaining.hasDotOrDotDot()) {
throw new IllegalArgumentException("Unable to compute relative "
+ " path from " + this + " to " + obj);
}
if (baseRemaining.isEmpty())
return childRemaining;
// number of ".." needed
int dotdots = baseRemaining.getNameCount();
if (dotdots == 0) {
return childRemaining;
}
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
for (int j=i; j<bn; j++) { for (int j=0; j<dotdots; j++) {
result.append("..\\"); result.append("..\\");
} }
// append remaining names in child // append remaining names in child
if (!other.isEmpty()) { if (!isChildEmpty) {
for (int j=i; j<cn; j++) { for (int j=0; j<childRemaining.getNameCount(); j++) {
result.append(other.getName(j).toString()); result.append(childRemaining.getName(j).toString());
result.append("\\"); result.append("\\");
} }
} }
// drop trailing slash in result // drop trailing slash
result.setLength(result.length()-1); result.setLength(result.length()-1);
return createFromNormalizedPath(getFileSystem(), result.toString()); return createFromNormalizedPath(getFileSystem(), result.toString());
} }
@Override @Override
public Path normalize() { public WindowsPath normalize() {
final int count = getNameCount(); final int count = getNameCount();
if (count == 0 || isEmpty()) if (count == 0 || isEmpty())
return this; return this;

View File

@ -390,35 +390,27 @@ public final class KdcComm {
for (int i=1; i <= retries; i++) { for (int i=1; i <= retries; i++) {
String proto = useTCP?"TCP":"UDP"; String proto = useTCP?"TCP":"UDP";
try (NetClient kdcClient = NetClient.getInstance( if (DEBUG) {
proto, kdc, port, timeout)) { System.out.println(">>> KDCCommunication: kdc=" + kdc
if (DEBUG) {
System.out.println(">>> KDCCommunication: kdc=" + kdc
+ " " + proto + ":" + " " + proto + ":"
+ port + ", timeout=" + port + ", timeout="
+ timeout + timeout
+ ",Attempt =" + i + ",Attempt =" + i
+ ", #bytes=" + obuf.length); + ", #bytes=" + obuf.length);
}
try (NetClient kdcClient = NetClient.getInstance(
proto, kdc, port, timeout)) {
kdcClient.send(obuf);
ibuf = kdcClient.receive();
break;
} catch (SocketTimeoutException se) {
if (DEBUG) {
System.out.println ("SocketTimeOutException with " +
"attempt: " + i);
} }
try { if (i == retries) {
/* ibuf = null;
* Send the data to the kdc. throw se;
*/
kdcClient.send(obuf);
/*
* And get a response.
*/
ibuf = kdcClient.receive();
break;
} catch (SocketTimeoutException se) {
if (DEBUG) {
System.out.println ("SocketTimeOutException with " +
"attempt: " + i);
}
if (i == retries) {
ibuf = null;
throw se;
}
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -3204,7 +3204,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* this method is called on a closed <code>CallableStatement</code> * this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @since 1.4
*/ */
public void setNull(String parameterName, int sqlType) throws SQLException { public void setNull(String parameterName, int sqlType) throws SQLException {
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3240,7 +3239,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* this method is called on a closed <code>CallableStatement</code> * this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @since 1.4
*/ */
public void setNull (String parameterName, int sqlType, String typeName) public void setNull (String parameterName, int sqlType, String typeName)
throws SQLException{ throws SQLException{
@ -3259,7 +3257,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setBoolean(String parameterName, boolean x) throws SQLException{ public void setBoolean(String parameterName, boolean x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3277,7 +3274,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setByte(String parameterName, byte x) throws SQLException{ public void setByte(String parameterName, byte x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3295,7 +3291,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setShort(String parameterName, short x) throws SQLException{ public void setShort(String parameterName, short x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3313,7 +3308,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setInt(String parameterName, int x) throws SQLException{ public void setInt(String parameterName, int x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3332,7 +3326,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setLong(String parameterName, long x) throws SQLException{ public void setLong(String parameterName, long x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3350,7 +3343,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setFloat(String parameterName, float x) throws SQLException{ public void setFloat(String parameterName, float x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3368,7 +3360,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setDouble(String parameterName, double x) throws SQLException{ public void setDouble(String parameterName, double x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3387,7 +3378,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{ public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3408,7 +3398,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setString(String parameterName, String x) throws SQLException{ public void setString(String parameterName, String x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3428,7 +3417,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setBytes(String parameterName, byte x[]) throws SQLException{ public void setBytes(String parameterName, byte x[]) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -3447,7 +3435,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setTimestamp(String parameterName, java.sql.Timestamp x) public void setTimestamp(String parameterName, java.sql.Timestamp x)
throws SQLException{ throws SQLException{
@ -3474,7 +3461,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* this method is called on a closed <code>CallableStatement</code> * this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @since 1.4
*/ */
public void setAsciiStream(String parameterName, java.io.InputStream x, int length) public void setAsciiStream(String parameterName, java.io.InputStream x, int length)
throws SQLException{ throws SQLException{
@ -3500,7 +3486,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* this method is called on a closed <code>CallableStatement</code> * this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @since 1.4
*/ */
public void setBinaryStream(String parameterName, java.io.InputStream x, public void setBinaryStream(String parameterName, java.io.InputStream x,
int length) throws SQLException{ int length) throws SQLException{
@ -3528,7 +3513,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* this method is called on a closed <code>CallableStatement</code> * this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @since 1.4
*/ */
public void setCharacterStream(String parameterName, public void setCharacterStream(String parameterName,
java.io.Reader reader, java.io.Reader reader,
@ -3684,7 +3668,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* this data type * this data type
* @see Types * @see Types
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setObject(String parameterName, Object x, int targetSqlType, int scale) public void setObject(String parameterName, Object x, int targetSqlType, int scale)
throws SQLException{ throws SQLException{
@ -3710,7 +3693,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* or <code>STRUCT</code> data type and the JDBC driver does not support * or <code>STRUCT</code> data type and the JDBC driver does not support
* this data type * this data type
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setObject(String parameterName, Object x, int targetSqlType) public void setObject(String parameterName, Object x, int targetSqlType)
throws SQLException{ throws SQLException{
@ -3751,7 +3733,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setObject(String parameterName, Object x) throws SQLException{ public void setObject(String parameterName, Object x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");
@ -4024,7 +4005,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setDate(String parameterName, java.sql.Date x) public void setDate(String parameterName, java.sql.Date x)
throws SQLException { throws SQLException {
@ -4050,7 +4030,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setDate(String parameterName, java.sql.Date x, Calendar cal) public void setDate(String parameterName, java.sql.Date x, Calendar cal)
throws SQLException { throws SQLException {
@ -4069,7 +4048,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setTime(String parameterName, java.sql.Time x) public void setTime(String parameterName, java.sql.Time x)
throws SQLException { throws SQLException {
@ -4095,7 +4073,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setTime(String parameterName, java.sql.Time x, Calendar cal) public void setTime(String parameterName, java.sql.Time x, Calendar cal)
throws SQLException { throws SQLException {
@ -4121,7 +4098,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method * this method
* @see #getParams * @see #getParams
* @since 1.4
*/ */
public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal) public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
throws SQLException { throws SQLException {
@ -4459,7 +4435,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable {
* @exception SQLException if a database access error occurs or * @exception SQLException if a database access error occurs or
* this method is called on a closed <code>PreparedStatement</code> * this method is called on a closed <code>PreparedStatement</code>
* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
* @since 1.4
*/ */
public void setURL(int parameterIndex, java.net.URL x) throws SQLException { public void setURL(int parameterIndex, java.net.URL x) throws SQLException {
throw new SQLFeatureNotSupportedException("Feature not supported"); throw new SQLFeatureNotSupportedException("Feature not supported");

View File

@ -57,7 +57,6 @@ public interface CommonDataSource {
* logging is disabled * logging is disabled
* @exception java.sql.SQLException if a database access error occurs * @exception java.sql.SQLException if a database access error occurs
* @see #setLogWriter * @see #setLogWriter
* @since 1.4
*/ */
java.io.PrintWriter getLogWriter() throws SQLException; java.io.PrintWriter getLogWriter() throws SQLException;
@ -79,7 +78,6 @@ public interface CommonDataSource {
* @param out the new log writer; to disable logging, set to null * @param out the new log writer; to disable logging, set to null
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
* @see #getLogWriter * @see #getLogWriter
* @since 1.4
*/ */
void setLogWriter(java.io.PrintWriter out) throws SQLException; void setLogWriter(java.io.PrintWriter out) throws SQLException;
@ -94,7 +92,6 @@ public interface CommonDataSource {
* @param seconds the data source login time limit * @param seconds the data source login time limit
* @exception SQLException if a database access error occurs. * @exception SQLException if a database access error occurs.
* @see #getLoginTimeout * @see #getLoginTimeout
* @since 1.4
*/ */
void setLoginTimeout(int seconds) throws SQLException; void setLoginTimeout(int seconds) throws SQLException;
@ -109,7 +106,6 @@ public interface CommonDataSource {
* @return the data source login time limit * @return the data source login time limit
* @exception SQLException if a database access error occurs. * @exception SQLException if a database access error occurs.
* @see #setLoginTimeout * @see #setLoginTimeout
* @since 1.4
*/ */
int getLoginTimeout() throws SQLException; int getLoginTimeout() throws SQLException;

View File

@ -72,6 +72,34 @@ public interface ConnectionPoolDataSource extends CommonDataSource {
PooledConnection getPooledConnection(String user, String password) PooledConnection getPooledConnection(String user, String password)
throws SQLException; throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
java.io.PrintWriter getLogWriter() throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
void setLogWriter(java.io.PrintWriter out) throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
void setLoginTimeout(int seconds) throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
int getLoginTimeout() throws SQLException;
//------------------------- JDBC 4.3 ----------------------------------- //------------------------- JDBC 4.3 -----------------------------------
/** /**

View File

@ -109,6 +109,34 @@ public interface DataSource extends CommonDataSource, Wrapper {
Connection getConnection(String username, String password) Connection getConnection(String username, String password)
throws SQLException; throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
java.io.PrintWriter getLogWriter() throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
void setLogWriter(java.io.PrintWriter out) throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
void setLoginTimeout(int seconds) throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
int getLoginTimeout() throws SQLException;
// JDBC 4.3 // JDBC 4.3
/** /**

View File

@ -81,7 +81,35 @@ public interface XADataSource extends CommonDataSource {
XAConnection getXAConnection(String user, String password) XAConnection getXAConnection(String user, String password)
throws SQLException; throws SQLException;
// JDBC 4.3 /**
* {@inheritDoc}
* @since 1.4
*/
@Override
java.io.PrintWriter getLogWriter() throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
void setLogWriter(java.io.PrintWriter out) throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
void setLoginTimeout(int seconds) throws SQLException;
/**
* {@inheritDoc}
* @since 1.4
*/
@Override
int getLoginTimeout() throws SQLException;
// JDBC 4.3
/** /**
* Creates a new {@code XAConnectionBuilder} instance * Creates a new {@code XAConnectionBuilder} instance

View File

@ -150,7 +150,7 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi {
this.macAlgorithm.init(secretKey); this.macAlgorithm.init(secretKey);
} catch (InvalidKeyException ex) { } catch (InvalidKeyException ex) {
// reinstantiate Mac object to work around bug in JDK // reinstantiate Mac object to work around bug in JDK
// see: http://bugs.sun.com/view_bug.do?bug_id=4953555 // see: http://bugs.java.com/view_bug.do?bug_id=4953555
Mac mac = this.macAlgorithm; Mac mac = this.macAlgorithm;
try { try {
this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm()); this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm());

View File

@ -112,7 +112,7 @@ public abstract class SignatureBaseRSA extends SignatureAlgorithmSpi {
this.signatureAlgorithm.initVerify((PublicKey) publicKey); this.signatureAlgorithm.initVerify((PublicKey) publicKey);
} catch (InvalidKeyException ex) { } catch (InvalidKeyException ex) {
// reinstantiate Signature object to work around bug in JDK // reinstantiate Signature object to work around bug in JDK
// see: http://bugs.sun.com/view_bug.do?bug_id=4953555 // see: http://bugs.java.com/view_bug.do?bug_id=4953555
Signature sig = this.signatureAlgorithm; Signature sig = this.signatureAlgorithm;
try { try {
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm()); this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());

View File

@ -139,7 +139,7 @@ public class SignatureDSA extends SignatureAlgorithmSpi {
this.signatureAlgorithm.initVerify((PublicKey) publicKey); this.signatureAlgorithm.initVerify((PublicKey) publicKey);
} catch (InvalidKeyException ex) { } catch (InvalidKeyException ex) {
// reinstantiate Signature object to work around bug in JDK // reinstantiate Signature object to work around bug in JDK
// see: http://bugs.sun.com/view_bug.do?bug_id=4953555 // see: http://bugs.java.com/view_bug.do?bug_id=4953555
Signature sig = this.signatureAlgorithm; Signature sig = this.signatureAlgorithm;
try { try {
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm()); this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());

View File

@ -252,7 +252,7 @@ public abstract class SignatureECDSA extends SignatureAlgorithmSpi {
this.signatureAlgorithm.initVerify((PublicKey) publicKey); this.signatureAlgorithm.initVerify((PublicKey) publicKey);
} catch (InvalidKeyException ex) { } catch (InvalidKeyException ex) {
// reinstantiate Signature object to work around bug in JDK // reinstantiate Signature object to work around bug in JDK
// see: http://bugs.sun.com/view_bug.do?bug_id=4953555 // see: http://bugs.java.com/view_bug.do?bug_id=4953555
Signature sig = this.signatureAlgorithm; Signature sig = this.signatureAlgorithm;
try { try {
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm()); this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());

View File

@ -21,7 +21,7 @@
* under the License. * under the License.
*/ */
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/ */
/* /*
* $Id: ApacheTransform.java 1333869 2012-05-04 10:42:44Z coheigea $ * $Id: ApacheTransform.java 1333869 2012-05-04 10:42:44Z coheigea $
@ -38,7 +38,6 @@ import org.w3c.dom.Node;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.transforms.Transform; import com.sun.org.apache.xml.internal.security.transforms.Transform;
import com.sun.org.apache.xml.internal.security.transforms.Transforms;
import javax.xml.crypto.*; import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext; import javax.xml.crypto.dom.DOMCryptoContext;
@ -150,7 +149,7 @@ public abstract class ApacheTransform extends TransformService {
if (Utils.secureValidation(xc)) { if (Utils.secureValidation(xc)) {
String algorithm = getAlgorithm(); String algorithm = getAlgorithm();
if (Transforms.TRANSFORM_XSLT.equals(algorithm)) { if (Policy.restrictAlg(algorithm)) {
throw new TransformException( throw new TransformException(
"Transform " + algorithm + " is forbidden when secure validation is enabled" "Transform " + algorithm + " is forbidden when secure validation is enabled"
); );

View File

@ -21,7 +21,7 @@
* under the License. * under the License.
*/ */
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/ */
/* /*
* $Id: DOMManifest.java 1333415 2012-05-03 12:03:51Z coheigea $ * $Id: DOMManifest.java 1333415 2012-05-03 12:03:51Z coheigea $
@ -110,9 +110,10 @@ public final class DOMManifest extends DOMStructure implements Manifest {
localName + ", expected Reference"); localName + ", expected Reference");
} }
refs.add(new DOMReference(refElem, context, provider)); refs.add(new DOMReference(refElem, context, provider));
if (secVal && (refs.size() > DOMSignedInfo.MAXIMUM_REFERENCE_COUNT)) { if (secVal && Policy.restrictNumReferences(refs.size())) {
String error = "A maxiumum of " + DOMSignedInfo.MAXIMUM_REFERENCE_COUNT + " " String error = "A maximum of " + Policy.maxReferences()
+ "references per Manifest are allowed with secure validation"; + " references per Manifest are allowed when"
+ " secure validation is enabled";
throw new MarshalException(error); throw new MarshalException(error);
} }
refElem = DOMUtils.getNextSiblingElement(refElem); refElem = DOMUtils.getNextSiblingElement(refElem);

View File

@ -21,7 +21,7 @@
* under the License. * under the License.
*/ */
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/ */
/* /*
* =========================================================================== * ===========================================================================
@ -51,7 +51,6 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.jcp.xml.dsig.internal.DigesterOutputStream; import org.jcp.xml.dsig.internal.DigesterOutputStream;
import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm;
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException; import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.utils.Base64; import com.sun.org.apache.xml.internal.security.utils.Base64;
@ -66,11 +65,6 @@ import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream
public final class DOMReference extends DOMStructure public final class DOMReference extends DOMStructure
implements Reference, DOMURIReference { implements Reference, DOMURIReference {
/**
* The maximum number of transforms per reference, if secure validation is enabled.
*/
public static final int MAXIMUM_TRANSFORM_COUNT = 5;
/** /**
* Look up useC14N11 system property. If true, an explicit C14N11 transform * Look up useC14N11 system property. If true, an explicit C14N11 transform
* will be added if necessary when generating the signature. See section * will be added if necessary when generating the signature. See section
@ -208,9 +202,10 @@ public final class DOMReference extends DOMStructure
} }
transforms.add transforms.add
(new DOMTransform(transformElem, context, provider)); (new DOMTransform(transformElem, context, provider));
if (secVal && (transforms.size() > MAXIMUM_TRANSFORM_COUNT)) { if (secVal && Policy.restrictNumTransforms(transforms.size())) {
String error = "A maxiumum of " + MAXIMUM_TRANSFORM_COUNT + " " String error = "A maximum of " + Policy.maxTransforms()
+ "transforms per Reference are allowed with secure validation"; + " transforms per Reference are allowed when"
+ " secure validation is enabled";
throw new MarshalException(error); throw new MarshalException(error);
} }
transformElem = DOMUtils.getNextSiblingElement(transformElem); transformElem = DOMUtils.getNextSiblingElement(transformElem);
@ -227,10 +222,10 @@ public final class DOMReference extends DOMStructure
Element dmElem = nextSibling; Element dmElem = nextSibling;
this.digestMethod = DOMDigestMethod.unmarshal(dmElem); this.digestMethod = DOMDigestMethod.unmarshal(dmElem);
String digestMethodAlgorithm = this.digestMethod.getAlgorithm(); String digestMethodAlgorithm = this.digestMethod.getAlgorithm();
if (secVal if (secVal && Policy.restrictAlg(digestMethodAlgorithm)) {
&& MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5.equals(digestMethodAlgorithm)) {
throw new MarshalException( throw new MarshalException(
"It is forbidden to use algorithm " + digestMethod + " when secure validation is enabled" "It is forbidden to use algorithm " + digestMethodAlgorithm +
" when secure validation is enabled"
); );
} }

View File

@ -21,7 +21,7 @@
* under the License. * under the License.
*/ */
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/ */
/* /*
* =========================================================================== * ===========================================================================
@ -149,9 +149,10 @@ public final class DOMRetrievalMethod extends DOMStructure
} }
transforms.add transforms.add
(new DOMTransform(transformElem, context, provider)); (new DOMTransform(transformElem, context, provider));
if (secVal && (transforms.size() > DOMReference.MAXIMUM_TRANSFORM_COUNT)) { if (secVal && Policy.restrictNumTransforms(transforms.size())) {
String error = "A maxiumum of " + DOMReference.MAXIMUM_TRANSFORM_COUNT + " " String error = "A maximum of " + Policy.maxTransforms()
+ "transforms per Reference are allowed with secure validation"; + " transforms per Reference are allowed when"
+ " secure validation is enabled";
throw new MarshalException(error); throw new MarshalException(error);
} }
transformElem = DOMUtils.getNextSiblingElement(transformElem); transformElem = DOMUtils.getNextSiblingElement(transformElem);
@ -238,7 +239,8 @@ public final class DOMRetrievalMethod extends DOMStructure
} }
// guard against RetrievalMethod loops // guard against RetrievalMethod loops
if ((data instanceof NodeSetData) && Utils.secureValidation(context)) { if ((data instanceof NodeSetData) && Utils.secureValidation(context)
&& Policy.restrictRetrievalMethodLoops()) {
NodeSetData<?> nsd = (NodeSetData<?>)data; NodeSetData<?> nsd = (NodeSetData<?>)data;
Iterator<?> i = nsd.iterator(); Iterator<?> i = nsd.iterator();
if (i.hasNext()) { if (i.hasNext()) {

View File

@ -21,7 +21,7 @@
* under the License. * under the License.
*/ */
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/ */
/* /*
* $Id: DOMSignedInfo.java 1333415 2012-05-03 12:03:51Z coheigea $ * $Id: DOMSignedInfo.java 1333415 2012-05-03 12:03:51Z coheigea $
@ -45,7 +45,6 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import com.sun.org.apache.xml.internal.security.utils.Base64; import com.sun.org.apache.xml.internal.security.utils.Base64;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream; import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
/** /**
@ -55,22 +54,9 @@ import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream
*/ */
public final class DOMSignedInfo extends DOMStructure implements SignedInfo { public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
/**
* The maximum number of references per Manifest, if secure validation is enabled.
*/
public static final int MAXIMUM_REFERENCE_COUNT = 30;
private static java.util.logging.Logger log = private static java.util.logging.Logger log =
java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom"); java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
/** Signature - NOT Recommended RSAwithMD5 */
private static final String ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5 =
Constants.MoreAlgorithmsSpecNS + "rsa-md5";
/** HMAC - NOT Recommended HMAC-MD5 */
private static final String ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5 =
Constants.MoreAlgorithmsSpecNS + "hmac-md5";
private List<Reference> references; private List<Reference> references;
private CanonicalizationMethod canonicalizationMethod; private CanonicalizationMethod canonicalizationMethod;
private SignatureMethod signatureMethod; private SignatureMethod signatureMethod;
@ -158,10 +144,10 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
boolean secVal = Utils.secureValidation(context); boolean secVal = Utils.secureValidation(context);
String signatureMethodAlgorithm = signatureMethod.getAlgorithm(); String signatureMethodAlgorithm = signatureMethod.getAlgorithm();
if (secVal && ((ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5.equals(signatureMethodAlgorithm) if (secVal && Policy.restrictAlg(signatureMethodAlgorithm)) {
|| ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5.equals(signatureMethodAlgorithm)))) {
throw new MarshalException( throw new MarshalException(
"It is forbidden to use algorithm " + signatureMethod + " when secure validation is enabled" "It is forbidden to use algorithm " + signatureMethodAlgorithm +
" when secure validation is enabled"
); );
} }
@ -179,9 +165,10 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
} }
refList.add(new DOMReference(refElem, context, provider)); refList.add(new DOMReference(refElem, context, provider));
if (secVal && (refList.size() > MAXIMUM_REFERENCE_COUNT)) { if (secVal && Policy.restrictNumReferences(refList.size())) {
String error = "A maxiumum of " + MAXIMUM_REFERENCE_COUNT + " " String error = "A maximum of " + Policy.maxReferences()
+ "references per Manifest are allowed with secure validation"; + " references per Manifest are allowed when"
+ " secure validation is enabled";
throw new MarshalException(error); throw new MarshalException(error);
} }
refElem = DOMUtils.getNextSiblingElement(refElem); refElem = DOMUtils.getNextSiblingElement(refElem);

View File

@ -21,7 +21,7 @@
* under the License. * under the License.
*/ */
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/ */
/* /*
* $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $ * $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $
@ -73,6 +73,11 @@ public class DOMURIDereferencer implements URIDereferencer {
boolean secVal = Utils.secureValidation(context); boolean secVal = Utils.secureValidation(context);
if (secVal && Policy.restrictReferenceUriScheme(uri)) {
throw new URIReferenceException(
"Uri " + uri + " is forbidden when secure validation is enabled");
}
// Check if same-document URI and already registered on the context // Check if same-document URI and already registered on the context
if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') { if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') {
String id = uri.substring(1); String id = uri.substring(1);
@ -83,12 +88,19 @@ public class DOMURIDereferencer implements URIDereferencer {
id = id.substring(i1+1, i2); id = id.substring(i1+1, i2);
} }
Node referencedElem = dcc.getElementById(id); // check if element is registered by Id
Node referencedElem = uriAttr.getOwnerDocument().getElementById(id);
if (referencedElem == null) {
// see if element is registered in DOMCryptoContext
referencedElem = dcc.getElementById(id);
}
if (referencedElem != null) { if (referencedElem != null) {
if (secVal) { if (secVal && Policy.restrictDuplicateIds()) {
Element start = referencedElem.getOwnerDocument().getDocumentElement(); Element start = referencedElem.getOwnerDocument().getDocumentElement();
if (!XMLUtils.protectAgainstWrappingAttack(start, (Element)referencedElem, id)) { if (!XMLUtils.protectAgainstWrappingAttack(start, (Element)referencedElem, id)) {
String error = "Multiple Elements with the same ID " + id + " were detected"; String error = "Multiple Elements with the same ID "
+ id + " detected when secure validation"
+ " is enabled";
throw new URIReferenceException(error); throw new URIReferenceException(error);
} }
} }
@ -110,9 +122,9 @@ public class DOMURIDereferencer implements URIDereferencer {
try { try {
ResourceResolver apacheResolver = ResourceResolver apacheResolver =
ResourceResolver.getInstance(uriAttr, baseURI, secVal); ResourceResolver.getInstance(uriAttr, baseURI, false);
XMLSignatureInput in = apacheResolver.resolve(uriAttr, XMLSignatureInput in = apacheResolver.resolve(uriAttr,
baseURI, secVal); baseURI, false);
if (in.isOctetStream()) { if (in.isOctetStream()) {
return new ApacheOctetStreamData(in); return new ApacheOctetStreamData(in);
} else { } else {

View File

@ -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);
}
}

View File

@ -358,7 +358,9 @@ final class P11RSACipher extends CipherSpi {
System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs); System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs);
tmpBuffer = p11.C_Sign(session.id(), tmpBuffer); tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
if (tmpBuffer.length > outLen) { if (tmpBuffer.length > outLen) {
throw new BadPaddingException("Output buffer too small"); throw new BadPaddingException(
"Output buffer (" + outLen + ") is too small to " +
"hold the produced data (" + tmpBuffer.length + ")");
} }
System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length); System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
n = tmpBuffer.length; n = tmpBuffer.length;

View File

@ -558,7 +558,7 @@ void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR
pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy); pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
if (pCharArray == NULL) { return; } if (pCharArray == NULL) { return; }
*ckpLength = strlen(pCharArray); *ckpLength = (CK_ULONG) strlen(pCharArray);
*ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR)); *ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
if (*ckpArray == NULL) { if (*ckpArray == NULL) {
(*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray); (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -49,6 +49,7 @@ void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
(JNIEnv *env, jclass thisClass, jstring jLibName) (JNIEnv *env, jclass thisClass, jstring jLibName)
{ {
void *hModule;
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL); const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
if (libName == NULL) { if (libName == NULL) {
return 0L; return 0L;
@ -56,9 +57,9 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
// look up existing handle only, do not load // look up existing handle only, do not load
#if defined(AIX) #if defined(AIX)
void *hModule = dlopen(libName, RTLD_LAZY); hModule = dlopen(libName, RTLD_LAZY);
#else #else
void *hModule = dlopen(libName, RTLD_NOLOAD); hModule = dlopen(libName, RTLD_NOLOAD);
#endif #endif
dprintf2("-handle for %s: %u\n", libName, hModule); dprintf2("-handle for %s: %u\n", libName, hModule);
(*env)->ReleaseStringUTFChars(env, jLibName, libName); (*env)->ReleaseStringUTFChars(env, jLibName, libName);

View File

@ -31,6 +31,9 @@
#include "j2secmod.h" #include "j2secmod.h"
extern void throwNullPointerException(JNIEnv *env, const char *message);
extern void throwIOException(JNIEnv *env, const char *message);
void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) { void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
HINSTANCE hModule = (HINSTANCE)jHandle; HINSTANCE hModule = (HINSTANCE)jHandle;
void *fAddress = GetProcAddress(hModule, functionName); void *fAddress = GetProcAddress(hModule, functionName);

View File

@ -24,5 +24,5 @@
*/ */
module jdk.internal.opt { module jdk.internal.opt {
exports jdk.internal.joptsimple to jdk.jlink; exports jdk.internal.joptsimple to jdk.jlink, jdk.jshell;
} }

View File

@ -78,28 +78,21 @@ public final class DefaultImageBuilder implements ImageBuilder {
private final List<String> args; private final List<String> args;
private final Set<String> modules; private final Set<String> modules;
public DefaultExecutableImage(Path home, Set<String> modules) { DefaultExecutableImage(Path home, Set<String> modules) {
this(home, modules, createArgs(home));
}
private DefaultExecutableImage(Path home, Set<String> modules,
List<String> args) {
Objects.requireNonNull(home); Objects.requireNonNull(home);
Objects.requireNonNull(args);
if (!Files.exists(home)) { if (!Files.exists(home)) {
throw new IllegalArgumentException("Invalid image home"); throw new IllegalArgumentException("Invalid image home");
} }
this.home = home; this.home = home;
this.modules = Collections.unmodifiableSet(modules); this.modules = Collections.unmodifiableSet(modules);
this.args = Collections.unmodifiableList(args); this.args = createArgs(home);
} }
private static List<String> createArgs(Path home) { private static List<String> createArgs(Path home) {
Objects.requireNonNull(home); Objects.requireNonNull(home);
List<String> javaArgs = new ArrayList<>(); Path binDir = home.resolve("bin");
javaArgs.add(home.resolve("bin"). String java = Files.exists(binDir.resolve("java"))? "java" : "java.exe";
resolve(getJavaProcessName()).toString()); return List.of(binDir.resolve(java).toString());
return javaArgs;
} }
@Override @Override
@ -130,6 +123,7 @@ public final class DefaultImageBuilder implements ImageBuilder {
private final Path root; private final Path root;
private final Path mdir; private final Path mdir;
private final Set<String> modules = new HashSet<>(); private final Set<String> modules = new HashSet<>();
private String targetOsName;
/** /**
* Default image builder constructor. * Default image builder constructor.
@ -171,6 +165,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
@Override @Override
public void storeFiles(ResourcePool files) { public void storeFiles(ResourcePool files) {
try { try {
// populate release properties up-front. targetOsName
// field is assigned from there and used elsewhere.
Properties release = releaseProperties(files);
Path bin = root.resolve("bin");
files.entries().forEach(f -> { files.entries().forEach(f -> {
if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) { if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
try { try {
@ -186,11 +185,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
modules.add(m.name()); modules.add(m.name());
} }
}); });
storeFiles(modules, releaseProperties(files));
storeFiles(modules, release);
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) { if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
// launchers in the bin directory need execute permission // launchers in the bin directory need execute permission
Path bin = root.resolve("bin");
if (Files.isDirectory(bin)) { if (Files.isDirectory(bin)) {
Files.list(bin) Files.list(bin)
.filter(f -> !f.toString().endsWith(".diz")) .filter(f -> !f.toString().endsWith(".diz"))
@ -208,7 +207,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
} }
} }
prepareApplicationFiles(files, modules); // If native files are stripped completely, <root>/bin dir won't exist!
// So, don't bother generating launcher scripts.
if (Files.isDirectory(bin)) {
prepareApplicationFiles(files, modules);
}
} catch (IOException ex) { } catch (IOException ex) {
throw new PluginException(ex); throw new PluginException(ex);
} }
@ -226,6 +229,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
props.setProperty("JAVA_VERSION", System.getProperty("java.version")); props.setProperty("JAVA_VERSION", System.getProperty("java.version"));
}); });
this.targetOsName = props.getProperty("OS_NAME");
if (this.targetOsName == null) {
throw new PluginException("TargetPlatform attribute is missing for java.base module");
}
Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release"); Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
if (release.isPresent()) { if (release.isPresent()) {
try (InputStream is = release.get().content()) { try (InputStream is = release.get().content()) {
@ -373,7 +381,7 @@ public final class DefaultImageBuilder implements ImageBuilder {
Files.createLink(dstFile, target); Files.createLink(dstFile, target);
} }
private static String nativeDir(String filename) { private String nativeDir(String filename) {
if (isWindows()) { if (isWindows()) {
if (filename.endsWith(".dll") || filename.endsWith(".diz") if (filename.endsWith(".dll") || filename.endsWith(".diz")
|| filename.endsWith(".pdb") || filename.endsWith(".map")) { || filename.endsWith(".pdb") || filename.endsWith(".map")) {
@ -386,8 +394,8 @@ public final class DefaultImageBuilder implements ImageBuilder {
} }
} }
private static boolean isWindows() { private boolean isWindows() {
return System.getProperty("os.name").startsWith("Windows"); return targetOsName.startsWith("Windows");
} }
/** /**
@ -452,12 +460,10 @@ public final class DefaultImageBuilder implements ImageBuilder {
} }
} }
private static String getJavaProcessName() {
return isWindows() ? "java.exe" : "java";
}
public static ExecutableImage getExecutableImage(Path root) { public static ExecutableImage getExecutableImage(Path root) {
if (Files.exists(root.resolve("bin").resolve(getJavaProcessName()))) { Path binDir = root.resolve("bin");
if (Files.exists(binDir.resolve("java")) ||
Files.exists(binDir.resolve("java.exe"))) {
return new DefaultExecutableImage(root, retrieveModules(root)); return new DefaultExecutableImage(root, retrieveModules(root));
} }
return null; return null;

View File

@ -172,7 +172,7 @@ public final class ImagePluginStack {
private final Plugin lastSorter; private final Plugin lastSorter;
private final List<Plugin> plugins = new ArrayList<>(); private final List<Plugin> plugins = new ArrayList<>();
private final List<ResourcePrevisitor> resourcePrevisitors = new ArrayList<>(); private final List<ResourcePrevisitor> resourcePrevisitors = new ArrayList<>();
private final boolean validate;
public ImagePluginStack() { public ImagePluginStack() {
this(null, Collections.emptyList(), null); this(null, Collections.emptyList(), null);
@ -181,6 +181,13 @@ public final class ImagePluginStack {
public ImagePluginStack(ImageBuilder imageBuilder, public ImagePluginStack(ImageBuilder imageBuilder,
List<Plugin> plugins, List<Plugin> plugins,
Plugin lastSorter) { Plugin lastSorter) {
this(imageBuilder, plugins, lastSorter, true);
}
public ImagePluginStack(ImageBuilder imageBuilder,
List<Plugin> plugins,
Plugin lastSorter,
boolean validate) {
this.imageBuilder = Objects.requireNonNull(imageBuilder); this.imageBuilder = Objects.requireNonNull(imageBuilder);
this.lastSorter = lastSorter; this.lastSorter = lastSorter;
this.plugins.addAll(Objects.requireNonNull(plugins)); this.plugins.addAll(Objects.requireNonNull(plugins));
@ -190,6 +197,7 @@ public final class ImagePluginStack {
resourcePrevisitors.add((ResourcePrevisitor) p); resourcePrevisitors.add((ResourcePrevisitor) p);
} }
}); });
this.validate = validate;
} }
public void operate(ImageProvider provider) throws Exception { public void operate(ImageProvider provider) throws Exception {
@ -268,6 +276,7 @@ public final class ImagePluginStack {
frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList(); frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList();
} }
} }
return resPool; return resPool;
} }
@ -458,7 +467,11 @@ public final class ImagePluginStack {
throws Exception { throws Exception {
Objects.requireNonNull(original); Objects.requireNonNull(original);
Objects.requireNonNull(transformed); Objects.requireNonNull(transformed);
imageBuilder.storeFiles(new LastPoolManager(transformed).resourcePool()); ResourcePool lastPool = new LastPoolManager(transformed).resourcePool();
if (validate) {
ResourcePoolConfiguration.validate(lastPool);
}
imageBuilder.storeFiles(lastPool);
} }
public ExecutableImage getExecutableImage() throws IOException { public ExecutableImage getExecutableImage() throws IOException {

View File

@ -5,7 +5,7 @@
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classfile" exception as provided * particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code. * by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT

View File

@ -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());
}
}

View File

@ -24,7 +24,11 @@
*/ */
package jdk.tools.jlink.internal.plugins; package jdk.tools.jlink.internal.plugins;
import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
@ -32,6 +36,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.misc.SharedSecrets; import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaLangInvokeAccess; import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.tools.jlink.plugin.ResourcePoolEntry; import jdk.tools.jlink.plugin.ResourcePoolEntry;
@ -47,15 +52,9 @@ public final class GenerateJLIClassesPlugin implements Plugin {
private static final String NAME = "generate-jli-classes"; private static final String NAME = "generate-jli-classes";
private static final String BMH_PARAM = "bmh";
private static final String BMH_SPECIES_PARAM = "bmh-species";
private static final String DMH_PARAM = "dmh";
private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME); private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
private static final String DIRECT_METHOD_HANDLE = "java/lang/invoke/DirectMethodHandle$Holder"; private static final String DIRECT_HOLDER = "java/lang/invoke/DirectMethodHandle$Holder";
private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual"; private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual";
private static final String DMH_INVOKE_STATIC = "invokeStatic"; private static final String DMH_INVOKE_STATIC = "invokeStatic";
private static final String DMH_INVOKE_SPECIAL = "invokeSpecial"; private static final String DMH_INVOKE_SPECIAL = "invokeSpecial";
@ -63,15 +62,17 @@ public final class GenerateJLIClassesPlugin implements Plugin {
private static final String DMH_INVOKE_INTERFACE = "invokeInterface"; private static final String DMH_INVOKE_INTERFACE = "invokeInterface";
private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit"; private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit";
private static final String DELEGATING_METHOD_HANDLE = "java/lang/invoke/DelegatingMethodHandle$Holder"; private static final String DELEGATING_HOLDER = "java/lang/invoke/DelegatingMethodHandle$Holder";
private static final String BASIC_FORMS_HOLDER = "java/lang/invoke/LambdaForm$Holder";
private static final String BASIC_FORMS_HANDLE = "java/lang/invoke/LambdaForm$Holder"; private static final String INVOKERS_HOLDER = "java/lang/invoke/Invokers$Holder";
private static final JavaLangInvokeAccess JLIA private static final JavaLangInvokeAccess JLIA
= SharedSecrets.getJavaLangInvokeAccess(); = SharedSecrets.getJavaLangInvokeAccess();
List<String> speciesTypes; List<String> speciesTypes;
List<String> invokerTypes;
Map<String, List<String>> dmhMethods; Map<String, List<String>> dmhMethods;
public GenerateJLIClassesPlugin() { public GenerateJLIClassesPlugin() {
@ -116,22 +117,30 @@ public final class GenerateJLIClassesPlugin implements Plugin {
"LILL", "I", "LLILL"); "LILL", "I", "LLILL");
} }
/**
* @return the default invoker forms to generate.
*/
private static List<String> defaultInvokers() {
return List.of("LL_L", "LL_I", "LILL_I", "L6_L");
}
/** /**
* @return the list of default DirectMethodHandle methods to generate. * @return the list of default DirectMethodHandle methods to generate.
*/ */
public static Map<String, List<String>> defaultDMHMethods() { private static Map<String, List<String>> defaultDMHMethods() {
return Map.of( return Map.of(
DMH_INVOKE_VIRTUAL, List.of("_L", "L_L", "LI_I", "LL_V"), DMH_INVOKE_VIRTUAL, List.of("L_L", "LL_L", "LLI_I", "L3_V"),
DMH_INVOKE_SPECIAL, List.of("L_I", "L_L", "LF_L", "LD_L", "LL_L", DMH_INVOKE_SPECIAL, List.of("LL_I", "LL_L", "LLF_L", "LLD_L", "L3_L",
"L3_L", "L4_L", "L5_L", "L6_L", "L7_L", "LI_I", "LI_L", "LIL_I", "L4_L", "L5_L", "L6_L", "L7_L", "L8_L", "LLI_I", "LLI_L",
"LII_I", "LII_L", "LLI_L", "LLI_I", "LILI_I", "LIIL_L", "LLIL_I", "LLII_I", "LLII_L", "L3I_L", "L3I_I", "LLILI_I",
"LIILL_L", "LIILL_I", "LIIL_I", "LILIL_I", "LILILL_I", "LLIIL_L", "LLIILL_L", "LLIILL_I", "LLIIL_I", "LLILIL_I",
"LILII_I", "LI3_I", "LI3L_I", "LI3LL_I", "LI3_L", "LI4_I"), "LLILILL_I", "LLILII_I", "LLI3_I", "LLI3L_I", "LLI3LL_I",
DMH_INVOKE_STATIC, List.of("II_I", "IL_I", "ILIL_I", "ILII_I", "LLI3_L", "LLI4_I"),
"_I", "_L", "_V", "D_L", "F_L", "I_I", "II_L", "LI_L", DMH_INVOKE_STATIC, List.of("LII_I", "LIL_I", "LILIL_I", "LILII_I",
"L_V", "L_L", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L", "L_I", "L_L", "L_V", "LD_L", "LF_L", "LI_I", "LII_L", "LLI_L",
"L7_L", "L8_L", "L9_L", "L9I_L", "L9II_L", "L9IIL_L", "LL_V", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L", "L7_L",
"L10_L", "L11_L", "L12_L", "L13_L", "L13I_L", "L13II_L") "L8_L", "L9_L", "L10_L", "L10I_L", "L10II_L", "L10IIL_L",
"L11_L", "L12_L", "L13_L", "L14_L", "L14I_L", "L14II_L")
); );
} }
@ -150,72 +159,91 @@ public final class GenerateJLIClassesPlugin implements Plugin {
public void configure(Map<String, String> config) { public void configure(Map<String, String> config) {
String mainArgument = config.get(NAME); String mainArgument = config.get(NAME);
// Enable by default if (mainArgument != null && mainArgument.startsWith("@")) {
boolean bmhEnabled = true; File file = new File(mainArgument.substring(1));
boolean dmhEnabled = true; if (file.exists()) {
if (mainArgument != null) { speciesTypes = new ArrayList<>();
List<String> args = Arrays.asList(mainArgument.split(",")); invokerTypes = new ArrayList<>();
if (!args.contains(BMH_PARAM)) { dmhMethods = new HashMap<>();
bmhEnabled = false; Stream<String> lines = fileLines(file);
}
if (!args.contains(DMH_PARAM)) {
dmhEnabled = false;
}
}
if (!bmhEnabled) { lines.map(line -> line.split(" "))
speciesTypes = List.of(); .forEach(parts -> {
switch (parts[0]) {
case "[BMH_RESOLVE]":
speciesTypes.add(expandSignature(parts[1]));
break;
case "[LF_RESOLVE]":
String methodType = parts[3];
validateMethodType(methodType);
if (parts[1].contains("Invokers")) {
invokerTypes.add(methodType);
} else if (parts[1].contains("DirectMethodHandle")) {
String dmh = parts[2];
// ignore getObject etc for now (generated
// by default)
if (DMH_METHOD_TYPE_MAP.containsKey(dmh)) {
addDMHMethodType(dmh, methodType);
}
}
break;
default: break; // ignore
}
});
}
} else { } else {
String args = config.get(BMH_SPECIES_PARAM); List<String> bmhSpecies = defaultSpecies();
List<String> bmhSpecies;
if (args != null && !args.isEmpty()) {
bmhSpecies = Arrays.stream(args.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());
} else {
bmhSpecies = defaultSpecies();
}
// Expand BMH species signatures // Expand BMH species signatures
speciesTypes = bmhSpecies.stream() speciesTypes = bmhSpecies.stream()
.map(type -> expandSignature(type)) .map(type -> expandSignature(type))
.collect(Collectors.toList()); .collect(Collectors.toList());
}
// DirectMethodHandles invokerTypes = defaultInvokers();
if (!dmhEnabled) { validateMethodTypes(invokerTypes);
dmhMethods = Map.of();
} else { dmhMethods = defaultDMHMethods();
dmhMethods = new HashMap<>(); for (List<String> dmhMethodTypes : dmhMethods.values()) {
for (String dmhParam : DMH_METHOD_TYPE_MAP.keySet()) { validateMethodTypes(dmhMethodTypes);
String args = config.get(dmhParam);
if (args != null && !args.isEmpty()) {
List<String> dmhMethodTypes = Arrays.stream(args.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());
dmhMethods.put(dmhParam, dmhMethodTypes);
// Validation check
for (String type : dmhMethodTypes) {
String[] typeParts = type.split("_");
// check return type (second part)
if (typeParts.length != 2 || typeParts[1].length() != 1
|| "LJIFDV".indexOf(typeParts[1].charAt(0)) == -1) {
throw new PluginException(
"Method type signature must be of form [LJIFD]*_[LJIFDV]");
}
// expand and check arguments (first part)
expandSignature(typeParts[0]);
}
}
}
if (dmhMethods.isEmpty()) {
dmhMethods = defaultDMHMethods();
} }
} }
} }
private void addDMHMethodType(String dmh, String methodType) {
validateMethodType(methodType);
List<String> methodTypes = dmhMethods.get(dmh);
if (methodTypes == null) {
methodTypes = new ArrayList<>();
dmhMethods.put(dmh, methodTypes);
}
methodTypes.add(methodType);
}
private Stream<String> fileLines(File file) {
try {
return Files.lines(file.toPath());
} catch (IOException io) {
throw new PluginException("Couldn't read file");
}
}
private void validateMethodTypes(List<String> dmhMethodTypes) {
for (String type : dmhMethodTypes) {
validateMethodType(type);
}
}
private void validateMethodType(String type) {
String[] typeParts = type.split("_");
// check return type (second part)
if (typeParts.length != 2 || typeParts[1].length() != 1
|| "LJIFDV".indexOf(typeParts[1].charAt(0)) == -1) {
throw new PluginException(
"Method type signature must be of form [LJIFD]*_[LJIFDV]");
}
// expand and check arguments (first part)
expandSignature(typeParts[0]);
}
private static void requireBasicType(char c) { private static void requireBasicType(char c) {
if ("LIJFD".indexOf(c) < 0) { if ("LIJFD".indexOf(c) < 0) {
throw new PluginException( throw new PluginException(
@ -228,9 +256,10 @@ public final class GenerateJLIClassesPlugin implements Plugin {
// Copy all but DMH_ENTRY to out // Copy all but DMH_ENTRY to out
in.transformAndCopy(entry -> { in.transformAndCopy(entry -> {
// filter out placeholder entries // filter out placeholder entries
if (entry.path().equals(DIRECT_METHOD_HANDLE_ENTRY) || if (entry.path().equals(DIRECT_METHOD_HOLDER_ENTRY) ||
entry.path().equals(DELEGATING_METHOD_HANDLE_ENTRY) || entry.path().equals(DELEGATING_METHOD_HOLDER_ENTRY) ||
entry.path().equals(BASIC_FORMS_HANDLE_ENTRY)) { entry.path().equals(INVOKERS_HOLDER_ENTRY) ||
entry.path().equals(BASIC_FORMS_HOLDER_ENTRY)) {
return null; return null;
} else { } else {
return entry; return entry;
@ -265,42 +294,72 @@ public final class GenerateJLIClassesPlugin implements Plugin {
for (List<String> entry : dmhMethods.values()) { for (List<String> entry : dmhMethods.values()) {
count += entry.size(); count += entry.size();
} }
MethodType[] methodTypes = new MethodType[count]; MethodType[] directMethodTypes = new MethodType[count];
int[] dmhTypes = new int[count]; int[] dmhTypes = new int[count];
int index = 0; int index = 0;
for (Map.Entry<String, List<String>> entry : dmhMethods.entrySet()) { for (Map.Entry<String, List<String>> entry : dmhMethods.entrySet()) {
String dmhType = entry.getKey(); String dmhType = entry.getKey();
for (String type : entry.getValue()) { for (String type : entry.getValue()) {
methodTypes[index] = asMethodType(type); // The DMH type to actually ask for is retrieved by removing
// the first argument, which needs to be of Object.class
MethodType mt = asMethodType(type);
if (mt.parameterCount() < 1 ||
mt.parameterType(0) != Object.class) {
throw new PluginException(
"DMH type parameter must start with L");
}
directMethodTypes[index] = mt.dropParameterTypes(0, 1);
dmhTypes[index] = DMH_METHOD_TYPE_MAP.get(dmhType); dmhTypes[index] = DMH_METHOD_TYPE_MAP.get(dmhType);
index++; index++;
} }
} }
MethodType[] invokerMethodTypes = new MethodType[this.invokerTypes.size()];
for (int i = 0; i < invokerTypes.size(); i++) {
// The invoker type to ask for is retrieved by removing the first
// and the last argument, which needs to be of Object.class
MethodType mt = asMethodType(invokerTypes.get(i));
final int lastParam = mt.parameterCount() - 1;
if (mt.parameterCount() < 2 ||
mt.parameterType(0) != Object.class ||
mt.parameterType(lastParam) != Object.class) {
throw new PluginException(
"Invoker type parameter must start and end with L");
}
mt = mt.dropParameterTypes(lastParam, lastParam + 1);
invokerMethodTypes[i] = mt.dropParameterTypes(0, 1);
}
try { try {
byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes( byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes(
DIRECT_METHOD_HANDLE, methodTypes, dmhTypes); DIRECT_HOLDER, directMethodTypes, dmhTypes);
ResourcePoolEntry ndata = ResourcePoolEntry ResourcePoolEntry ndata = ResourcePoolEntry
.create(DIRECT_METHOD_HANDLE_ENTRY, bytes); .create(DIRECT_METHOD_HOLDER_ENTRY, bytes);
out.add(ndata); out.add(ndata);
bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes( bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes(
DELEGATING_METHOD_HANDLE, methodTypes); DELEGATING_HOLDER, directMethodTypes);
ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HANDLE_ENTRY, bytes); ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HOLDER_ENTRY, bytes);
out.add(ndata); out.add(ndata);
bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HANDLE); bytes = JLIA.generateInvokersHolderClassBytes(INVOKERS_HOLDER,
ndata = ResourcePoolEntry.create(BASIC_FORMS_HANDLE_ENTRY, bytes); invokerMethodTypes);
ndata = ResourcePoolEntry.create(INVOKERS_HOLDER_ENTRY, bytes);
out.add(ndata);
bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HOLDER);
ndata = ResourcePoolEntry.create(BASIC_FORMS_HOLDER_ENTRY, bytes);
out.add(ndata); out.add(ndata);
} catch (Exception ex) { } catch (Exception ex) {
throw new PluginException(ex); throw new PluginException(ex);
} }
} }
private static final String DIRECT_METHOD_HANDLE_ENTRY = private static final String DIRECT_METHOD_HOLDER_ENTRY =
"/java.base/" + DIRECT_METHOD_HANDLE + ".class"; "/java.base/" + DIRECT_HOLDER + ".class";
private static final String DELEGATING_METHOD_HANDLE_ENTRY = private static final String DELEGATING_METHOD_HOLDER_ENTRY =
"/java.base/" + DELEGATING_METHOD_HANDLE + ".class"; "/java.base/" + DELEGATING_HOLDER + ".class";
private static final String BASIC_FORMS_HANDLE_ENTRY = private static final String BASIC_FORMS_HOLDER_ENTRY =
"/java.base/" + BASIC_FORMS_HANDLE + ".class"; "/java.base/" + BASIC_FORMS_HOLDER + ".class";
private static final String INVOKERS_HOLDER_ENTRY =
"/java.base/" + INVOKERS_HOLDER + ".class";
// Convert LL -> LL, L3 -> LLL // Convert LL -> LL, L3 -> LLL
private static String expandSignature(String signature) { private static String expandSignature(String signature) {

View File

@ -56,7 +56,7 @@ copy-files.argument=<List of <file path>=<image target> to copy to the image>.
copy-files.description=\ copy-files.description=\
If files to copy are not absolute path, JDK home dir is used.\n\ If files to copy are not absolute path, JDK home dir is used.\n\
e.g.: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewehere/conf.txt e.g.: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewhere/conf.txt
exclude-files.argument=<pattern-list> of files to exclude exclude-files.argument=<pattern-list> of files to exclude
@ -68,10 +68,12 @@ exclude-resources.argument=<pattern-list> resources to exclude
exclude-resources.description=\ exclude-resources.description=\
Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/** Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/**
generate-jli-classes.argument=<bmh[:bmh-species=LL,L3,...]> generate-jli-classes.argument=<@filename>
generate-jli-classes.description=\ generate-jli-classes.description=\
Concrete java.lang.invoke classes to generate Takes a file hinting to jlink what java.lang.invoke classes to pre-generate. If\n\
this flag is not specified a default set of classes will be generated, so to \n\
disable pre-generation supply the name of an empty or non-existing file
installed-modules.description=Fast loading of module descriptors (always enabled) installed-modules.description=Fast loading of module descriptors (always enabled)

View File

@ -165,8 +165,8 @@ class JarFileSystem extends ZipFileSystem {
walk(inode.child, process); walk(inode.child, process);
} else { } else {
process.accept(inode); process.accept(inode);
walk(inode.sibling, process);
} }
walk(inode.sibling, process);
} }
/** /**

View File

@ -124,10 +124,6 @@ java/beans/Introspector/8132566/OverrideUserDefPropertyInfoTest.java 8132565 gen
# jdk_lang # jdk_lang
java/lang/StringCoding/CheckEncodings.sh 7008363 generic-all java/lang/StringCoding/CheckEncodings.sh 7008363 generic-all
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java 8160690 generic-all
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java 8160690 generic-all
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java 8160690 generic-all
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java 8160690 generic-all
############################################################################ ############################################################################
@ -211,8 +207,6 @@ sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic-
java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all
sun/rmi/runtime/Log/6409194/NoConsoleOutput.java 8164124 windows-all
############################################################################ ############################################################################
# jdk_security # jdk_security

View File

@ -205,12 +205,13 @@ public class VerifyStackTrace {
.replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/") .replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/")
.replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run") .replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
.replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke") .replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke")
// DMHs may or may not be pre-generated, making frames differ // LFs may or may not be pre-generated, making frames differ
.replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH") .replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
.replaceAll("DMH\\.invoke", "DMH/xxxxxxxx.invoke") .replaceAll("Invokers\\$Holder", "LambdaForm\\$MH")
.replaceAll("MH\\.invoke", "MH/xxxxxxxx.invoke")
// invoke frames may or may not have basic method type // invoke frames may or may not have basic method type
// information encoded for diagnostic purposes // information encoded for diagnostic purposes
.replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z]+_[A-Z]", "xx.invoke$1") .replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z_]+", "xx.invoke$1")
.replaceAll("\\$[0-9]+", "\\$??"); .replaceAll("\\$[0-9]+", "\\$??");
} else { } else {
return produced; return produced;

View 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");
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -68,6 +68,7 @@ public class NoLoopbackPackets {
MulticastSocket msock = null; MulticastSocket msock = null;
List<SocketAddress> failedGroups = new ArrayList<SocketAddress>(); List<SocketAddress> failedGroups = new ArrayList<SocketAddress>();
Sender sender = null;
try { try {
msock = new MulticastSocket(); msock = new MulticastSocket();
int port = msock.getLocalPort(); int port = msock.getLocalPort();
@ -80,9 +81,8 @@ public class NoLoopbackPackets {
groups.add(new InetSocketAddress(InetAddress.getByName("::ffff:224.1.1.2"), port)); groups.add(new InetSocketAddress(InetAddress.getByName("::ffff:224.1.1.2"), port));
groups.add(new InetSocketAddress(InetAddress.getByName("ff02::1:1"), port)); groups.add(new InetSocketAddress(InetAddress.getByName("ff02::1:1"), port));
Thread sender = new Thread(new Sender(groups)); sender = new Sender(groups);
sender.setDaemon(true); // we want sender to stop when main thread exits new Thread(sender).start();
sender.start();
// Now try to receive multicast packets. we should not see any of them // Now try to receive multicast packets. we should not see any of them
// since we disable loopback mode. // since we disable loopback mode.
@ -107,6 +107,9 @@ public class NoLoopbackPackets {
} }
} finally { } finally {
if (msock != null) try { msock.close(); } catch (Exception e) {} if (msock != null) try { msock.close(); } catch (Exception e) {}
if (sender != null) {
sender.stop();
}
} }
if (failedGroups.size() > 0) { if (failedGroups.size() > 0) {
@ -119,6 +122,7 @@ public class NoLoopbackPackets {
static class Sender implements Runnable { static class Sender implements Runnable {
private List<SocketAddress> sendToGroups; private List<SocketAddress> sendToGroups;
private volatile boolean stop;
public Sender(List<SocketAddress> groups) { public Sender(List<SocketAddress> groups) {
sendToGroups = groups; sendToGroups = groups;
@ -136,7 +140,7 @@ public class NoLoopbackPackets {
MulticastSocket msock = new MulticastSocket(); MulticastSocket msock = new MulticastSocket();
msock.setLoopbackMode(true); // disable loopback mode msock.setLoopbackMode(true); // disable loopback mode
for (;;) { while (!stop) {
for (DatagramPacket packet : packets) { for (DatagramPacket packet : packets) {
msock.send(packet); msock.send(packet);
} }
@ -147,5 +151,9 @@ public class NoLoopbackPackets {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
void stop() {
stop = true;
}
} }
} }

View 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);
}
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -119,19 +119,31 @@ public class Basic {
ExecutorService pool = Executors.newCachedThreadPool(); ExecutorService pool = Executors.newCachedThreadPool();
AsynchronousChannelGroup group = AsynchronousChannelGroup AsynchronousChannelGroup group = AsynchronousChannelGroup
.withCachedThreadPool(pool, rand.nextInt(10)); .withCachedThreadPool(pool, rand.nextInt(10));
testShutdownWithChannels(pool, group); try {
testShutdownWithChannels(pool, group);
} finally {
group.shutdown();
}
} }
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
int nThreads = 1 + rand.nextInt(8); int nThreads = 1 + rand.nextInt(8);
AsynchronousChannelGroup group = AsynchronousChannelGroup AsynchronousChannelGroup group = AsynchronousChannelGroup
.withFixedThreadPool(nThreads, threadFactory); .withFixedThreadPool(nThreads, threadFactory);
testShutdownWithChannels(null, group); try {
testShutdownWithChannels(null, group);
} finally {
group.shutdown();
}
} }
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
ExecutorService pool = Executors.newCachedThreadPool(); ExecutorService pool = Executors.newCachedThreadPool();
AsynchronousChannelGroup group = AsynchronousChannelGroup AsynchronousChannelGroup group = AsynchronousChannelGroup
.withThreadPool(pool); .withThreadPool(pool);
testShutdownWithChannels(pool, group); try {
testShutdownWithChannels(pool, group);
} finally {
group.shutdown();
}
} }
} }
@ -164,19 +176,31 @@ public class Basic {
ExecutorService pool = pool = Executors.newCachedThreadPool(); ExecutorService pool = pool = Executors.newCachedThreadPool();
AsynchronousChannelGroup group = AsynchronousChannelGroup AsynchronousChannelGroup group = AsynchronousChannelGroup
.withCachedThreadPool(pool, rand.nextInt(5)); .withCachedThreadPool(pool, rand.nextInt(5));
testShutdownNow(pool, group); try {
testShutdownNow(pool, group);
} finally {
group.shutdown();
}
} }
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
int nThreads = 1 + rand.nextInt(8); int nThreads = 1 + rand.nextInt(8);
AsynchronousChannelGroup group = AsynchronousChannelGroup AsynchronousChannelGroup group = AsynchronousChannelGroup
.withFixedThreadPool(nThreads, threadFactory); .withFixedThreadPool(nThreads, threadFactory);
testShutdownNow(null, group); try {
testShutdownNow(null, group);
} finally {
group.shutdown();
}
} }
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
ExecutorService pool = Executors.newCachedThreadPool(); ExecutorService pool = Executors.newCachedThreadPool();
AsynchronousChannelGroup group = AsynchronousChannelGroup AsynchronousChannelGroup group = AsynchronousChannelGroup
.withThreadPool(pool); .withThreadPool(pool);
testShutdownNow(pool, group); try {
testShutdownNow(pool, group);
} finally {
group.shutdown();
}
} }
} }
@ -186,78 +210,78 @@ public class Basic {
AsynchronousChannelGroup group = AsynchronousChannelGroup group =
AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory); AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory);
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group); try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open(group); AsynchronousServerSocketChannel listener =
AsynchronousServerSocketChannel.open(group)) {
// initiate accept // initiate accept
listener.bind(new InetSocketAddress(0)); listener.bind(new InetSocketAddress(0));
Future<AsynchronousSocketChannel> result = listener.accept(); Future<AsynchronousSocketChannel> result = listener.accept();
// shutdown group // shutdown group
group.shutdown(); group.shutdown();
if (!group.isShutdown()) if (!group.isShutdown())
throw new RuntimeException("Group should be shutdown"); throw new RuntimeException("Group should be shutdown");
// attempt to create another channel // attempt to create another channel
try { try {
AsynchronousSocketChannel.open(group); AsynchronousSocketChannel.open(group);
throw new RuntimeException("ShutdownChannelGroupException expected"); throw new RuntimeException("ShutdownChannelGroupException expected");
} catch (ShutdownChannelGroupException x) { } catch (ShutdownChannelGroupException x) {
}
try {
AsynchronousServerSocketChannel.open(group);
throw new RuntimeException("ShutdownChannelGroupException expected");
} catch (ShutdownChannelGroupException x) {
}
// attempt to create another channel by connecting. This should cause
// the accept operation to fail.
InetAddress lh = InetAddress.getLocalHost();
int port = ((InetSocketAddress)listener.getLocalAddress()).getPort();
InetSocketAddress isa = new InetSocketAddress(lh, port);
ch.connect(isa).get();
try {
result.get();
throw new RuntimeException("Connection was accepted");
} catch (ExecutionException x) {
Throwable cause = x.getCause();
if (!(cause instanceof IOException))
throw new RuntimeException("Cause should be IOException");
cause = cause.getCause();
if (!(cause instanceof ShutdownChannelGroupException))
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
}
// initiate another accept even though channel group is shutdown.
Future<AsynchronousSocketChannel> res = listener.accept();
try {
res.get(3, TimeUnit.SECONDS);
throw new RuntimeException("TimeoutException expected");
} catch (TimeoutException x) {
}
// connect to the listener which should cause the accept to complete
AsynchronousSocketChannel.open().connect(isa);
try {
res.get();
throw new RuntimeException("Connection was accepted");
} catch (ExecutionException x) {
Throwable cause = x.getCause();
if (!(cause instanceof IOException))
throw new RuntimeException("Cause should be IOException");
cause = cause.getCause();
if (!(cause instanceof ShutdownChannelGroupException))
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
}
// group should *not* terminate as channels are open
boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
if (terminated) {
throw new RuntimeException("Group should not have terminated");
}
} finally {
group.shutdown();
} }
try {
AsynchronousServerSocketChannel.open(group);
throw new RuntimeException("ShutdownChannelGroupException expected");
} catch (ShutdownChannelGroupException x) {
}
// attempt to create another channel by connecting. This should cause
// the accept operation to fail.
InetAddress lh = InetAddress.getLocalHost();
int port = ((InetSocketAddress)listener.getLocalAddress()).getPort();
InetSocketAddress isa = new InetSocketAddress(lh, port);
ch.connect(isa).get();
try {
result.get();
throw new RuntimeException("Connection was accepted");
} catch (ExecutionException x) {
Throwable cause = x.getCause();
if (!(cause instanceof IOException))
throw new RuntimeException("Cause should be IOException");
cause = cause.getCause();
if (!(cause instanceof ShutdownChannelGroupException))
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
}
// initiate another accept even though channel group is shutdown.
Future<AsynchronousSocketChannel> res = listener.accept();
try {
res.get(3, TimeUnit.SECONDS);
throw new RuntimeException("TimeoutException expected");
} catch (TimeoutException x) {
}
// connect to the listener which should cause the accept to complete
AsynchronousSocketChannel.open().connect(isa);
try {
res.get();
throw new RuntimeException("Connection was accepted");
} catch (ExecutionException x) {
Throwable cause = x.getCause();
if (!(cause instanceof IOException))
throw new RuntimeException("Cause should be IOException");
cause = cause.getCause();
if (!(cause instanceof ShutdownChannelGroupException))
throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
}
// group should *not* terminate as channels are open
boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
if (terminated)
throw new RuntimeException("Group should not have terminated");
// close channel; group should terminate quickly
ch.close();
listener.close();
awaitTermination(group);
} }
static void miscTests() throws Exception { static void miscTests() throws Exception {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -41,34 +41,36 @@ import java.io.IOException;
public class GroupOfOne { public class GroupOfOne {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
final List<AsynchronousSocketChannel> accepted = new ArrayList<>();
// create listener to accept connections // create listener to accept connections
final AsynchronousServerSocketChannel listener = try (final AsynchronousServerSocketChannel listener =
AsynchronousServerSocketChannel.open() AsynchronousServerSocketChannel.open()) {
.bind(new InetSocketAddress(0));
final List<AsynchronousSocketChannel> accepted = new ArrayList<AsynchronousSocketChannel>(); listener.bind(new InetSocketAddress(0));
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() { listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
public void completed(AsynchronousSocketChannel ch, Void att) { public void completed(AsynchronousSocketChannel ch, Void att) {
synchronized (accepted) { synchronized (accepted) {
accepted.add(ch); accepted.add(ch);
}
listener.accept((Void)null, this);
} }
listener.accept((Void)null, this); public void failed(Throwable exc, Void att) {
} }
public void failed(Throwable exc, Void att) { });
}
});
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port); SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
test(sa, true, false); test(sa, true, false);
test(sa, false, true); test(sa, false, true);
test(sa, true, true); test(sa, true, true);
} finally {
// clean-up // clean-up
listener.close(); synchronized (accepted) {
synchronized (accepted) { for (AsynchronousSocketChannel ch: accepted) {
for (AsynchronousSocketChannel ch: accepted) { ch.close();
ch.close(); }
} }
} }
} }
@ -86,60 +88,60 @@ public class GroupOfOne {
return new Thread(r); return new Thread(r);
}}); }});
final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group); final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
try {
// the latch counts down when:
// 1. The read operation fails (expected)
// 2. the close/shutdown completes
final CountDownLatch latch = new CountDownLatch(2);
// the latch counts down when: ch.connect(sa, (Void)null, new CompletionHandler<Void,Void>() {
// 1. The read operation fails (expected) public void completed(Void result, Void att) {
// 2. the close/shutdown completes System.out.println("Connected");
final CountDownLatch latch = new CountDownLatch(2);
ch.connect(sa, (Void)null, new CompletionHandler<Void,Void>() { // initiate I/O operation that does not complete (successfully)
public void completed(Void result, Void att) { ByteBuffer buf = ByteBuffer.allocate(100);
System.out.println("Connected"); ch.read(buf, (Void)null, new CompletionHandler<Integer,Void>() {
public void completed(Integer bytesRead, Void att) {
throw new RuntimeException();
}
public void failed(Throwable exc, Void att) {
if (!(exc instanceof AsynchronousCloseException))
throw new RuntimeException(exc);
System.out.println("Read failed (expected)");
latch.countDown();
}
});
// initiate I/O operation that does not complete (successfully) // close channel or shutdown group
ByteBuffer buf = ByteBuffer.allocate(100); try {
ch.read(buf, (Void)null, new CompletionHandler<Integer,Void>() { if (closeChannel) {
public void completed(Integer bytesRead, Void att) { System.out.print("Close channel ...");
ch.close();
System.out.println(" done.");
}
if (shutdownGroup) {
System.out.print("Shutdown group ...");
group.shutdownNow();
System.out.println(" done.");
}
latch.countDown();
} catch (IOException e) {
throw new RuntimeException(); throw new RuntimeException();
} }
public void failed(Throwable exc, Void att) {
if (!(exc instanceof AsynchronousCloseException))
throw new RuntimeException(exc);
System.out.println("Read failed (expected)");
latch.countDown();
}
});
// close channel or shutdown group
try {
if (closeChannel) {
System.out.print("Close channel ...");
ch.close();
System.out.println(" done.");
}
if (shutdownGroup) {
System.out.print("Shutdown group ...");
group.shutdownNow();
System.out.println(" done.");
}
latch.countDown();
} catch (IOException e) {
throw new RuntimeException();
} }
} public void failed(Throwable exc, Void att) {
public void failed(Throwable exc, Void att) { throw new RuntimeException(exc);
throw new RuntimeException(exc); }
} });
});
latch.await();
// clean-up
group.shutdown();
boolean terminated = group.awaitTermination(20, TimeUnit.SECONDS);
if (!terminated)
throw new RuntimeException("Group did not terminate");
latch.await();
} finally {
// clean-up
group.shutdown();
boolean terminated = group.awaitTermination(20, TimeUnit.SECONDS);
if (!terminated)
throw new RuntimeException("Group did not terminate");
}
System.out.println("TEST OKAY"); System.out.println("TEST OKAY");
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -76,89 +76,91 @@ public class Identity {
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
// create listener to accept connections
final AsynchronousServerSocketChannel listener =
AsynchronousServerSocketChannel.open()
.bind(new InetSocketAddress(0));
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
public void completed(final AsynchronousSocketChannel ch, Void att) {
listener.accept((Void)null, this);
final ByteBuffer buf = ByteBuffer.allocate(100);
ch.read(buf, ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
public void completed(Integer bytesRead, AsynchronousSocketChannel ch) {
if (bytesRead < 0) {
try { ch.close(); } catch (IOException ignore) { }
} else {
buf.clear();
ch.read(buf, ch, this);
}
}
public void failed(Throwable exc, AsynchronousSocketChannel ch) {
try { ch.close(); } catch (IOException ignore) { }
}
});
}
public void failed(Throwable exc, Void att) {
}
});
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
// create 3-10 channels, each in its own group // create 3-10 channels, each in its own group
final int groupCount = 3 + rand.nextInt(8); final int groupCount = 3 + rand.nextInt(8);
AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount]; final AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount];
final AsynchronousSocketChannel[] channels = new AsynchronousSocketChannel[groupCount]; final AsynchronousSocketChannel[] channels = new AsynchronousSocketChannel[groupCount];
for (int i=0; i<groupCount; i++) {
ThreadFactory factory = createThreadFactory(i);
AsynchronousChannelGroup group;
if (rand.nextBoolean()) {
int nThreads = 1 + rand.nextInt(10);
group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
} else {
ExecutorService pool = Executors.newCachedThreadPool(factory);
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
}
groups[i] = group;
// create channel in group and connect it to the server // create listener to accept connections
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group); try (final AsynchronousServerSocketChannel listener =
ch.connect(sa).get(); AsynchronousServerSocketChannel.open()) {
channels[i] = ch;
}
// randomly write to each channel, ensuring that the completion handler listener.bind(new InetSocketAddress(0));
// is always invoked by a thread with the right identity. listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
final AtomicInteger writeCount = new AtomicInteger(100); public void completed(final AsynchronousSocketChannel ch, Void att) {
channels[0].write(getBuffer(), 0, new CompletionHandler<Integer,Integer>() { listener.accept((Void)null, this);
public void completed(Integer bytesWritten, Integer groupId) { final ByteBuffer buf = ByteBuffer.allocate(100);
if (bytesWritten != 1) ch.read(buf, ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
fail("Expected 1 byte to be written"); public void completed(Integer bytesRead, AsynchronousSocketChannel ch) {
if (!myGroup.get().equals(groupId)) if (bytesRead < 0) {
fail("Handler invoked by thread with the wrong identity"); try { ch.close(); } catch (IOException ignore) { }
if (writeCount.decrementAndGet() > 0) { } else {
int id = rand.nextInt(groupCount); buf.clear();
channels[id].write(getBuffer(), id, this); ch.read(buf, ch, this);
} else { }
done.countDown(); }
public void failed(Throwable exc, AsynchronousSocketChannel ch) {
try { ch.close(); } catch (IOException ignore) { }
}
});
} }
public void failed(Throwable exc, Void att) {
}
});
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
for (int i=0; i<groupCount; i++) {
ThreadFactory factory = createThreadFactory(i);
AsynchronousChannelGroup group;
if (rand.nextBoolean()) {
int nThreads = 1 + rand.nextInt(10);
group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
} else {
ExecutorService pool = Executors.newCachedThreadPool(factory);
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
}
groups[i] = group;
// create channel in group and connect it to the server
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
ch.connect(sa).get();
channels[i] = ch;
} }
public void failed(Throwable exc, Integer groupId) {
fail(exc.getMessage());
}
});
// wait until done // randomly write to each channel, ensuring that the completion handler
done.await(); // is always invoked by a thread with the right identity.
final AtomicInteger writeCount = new AtomicInteger(100);
channels[0].write(getBuffer(), 0, new CompletionHandler<Integer,Integer>() {
public void completed(Integer bytesWritten, Integer groupId) {
if (bytesWritten != 1)
fail("Expected 1 byte to be written");
if (!myGroup.get().equals(groupId))
fail("Handler invoked by thread with the wrong identity");
if (writeCount.decrementAndGet() > 0) {
int id = rand.nextInt(groupCount);
channels[id].write(getBuffer(), id, this);
} else {
done.countDown();
}
}
public void failed(Throwable exc, Integer groupId) {
fail(exc.getMessage());
}
});
// clean-up // wait until done
for (AsynchronousSocketChannel ch: channels) done.await();
ch.close(); } finally {
for (AsynchronousChannelGroup group: groups) // clean-up
group.shutdownNow(); for (AsynchronousSocketChannel ch: channels)
listener.close(); ch.close();
for (AsynchronousChannelGroup group: groups)
group.shutdownNow();
if (failed.get()) if (failed.get())
throw new RuntimeException("Test failed - see log for details"); throw new RuntimeException("Test failed - see log for details");
}
} }
static ByteBuffer getBuffer() { static ByteBuffer getBuffer() {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -66,21 +66,30 @@ public class Restart {
// group with fixed thread pool // group with fixed thread pool
int nThreads = 1 + rand.nextInt(4); int nThreads = 1 + rand.nextInt(4);
AsynchronousChannelGroup group = AsynchronousChannelGroup group =
AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory); AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
testRestart(group, 100); try {
group.shutdown(); testRestart(group, 100);
} finally {
group.shutdown();
}
// group with cached thread pool // group with cached thread pool
ExecutorService pool = Executors.newCachedThreadPool(factory); ExecutorService pool = Executors.newCachedThreadPool(factory);
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5)); group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
testRestart(group, 100); try {
group.shutdown(); testRestart(group, 100);
} finally {
group.shutdown();
}
// group with custom thread pool // group with custom thread pool
group = AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(
.withThreadPool(Executors.newFixedThreadPool(1+rand.nextInt(5), factory)); Executors.newFixedThreadPool(1+rand.nextInt(5), factory));
testRestart(group, 100); try {
group.shutdown(); testRestart(group, 100);
} finally {
group.shutdown();
}
// give time for threads to terminate // give time for threads to terminate
Thread.sleep(3000); Thread.sleep(3000);
@ -92,45 +101,43 @@ public class Restart {
static void testRestart(AsynchronousChannelGroup group, int count) static void testRestart(AsynchronousChannelGroup group, int count)
throws Exception throws Exception
{ {
AsynchronousServerSocketChannel listener = try (AsynchronousServerSocketChannel listener =
AsynchronousServerSocketChannel.open(group) AsynchronousServerSocketChannel.open(group)) {
.bind(new InetSocketAddress(0));
for (int i=0; i<count; i++) { listener.bind(new InetSocketAddress(0));
final CountDownLatch latch = new CountDownLatch(1); for (int i=0; i<count; i++) {
final CountDownLatch latch = new CountDownLatch(1);
listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() { listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
public void completed(AsynchronousSocketChannel ch, Void att) { public void completed(AsynchronousSocketChannel ch, Void att) {
try { try {
ch.close(); ch.close();
} catch (IOException ignore) { } } catch (IOException ignore) { }
latch.countDown(); latch.countDown();
// throw error or runtime exception // throw error or runtime exception
if (rand.nextBoolean()) { if (rand.nextBoolean()) {
throw new Error(); throw new Error();
} else { } else {
throw new RuntimeException(); throw new RuntimeException();
}
} }
} public void failed(Throwable exc, Void att) {
public void failed(Throwable exc, Void att) { }
} });
});
// establish loopback connection which should cause completion // establish loopback connection which should cause completion
// handler to be invoked. // handler to be invoked.
int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(); try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) {
InetAddress lh = InetAddress.getLocalHost(); InetAddress lh = InetAddress.getLocalHost();
ch.connect(new InetSocketAddress(lh, port)).get(); ch.connect(new InetSocketAddress(lh, port)).get();
ch.close(); }
// wait for handler to be invoked // wait for handler to be invoked
latch.await(); latch.await();
}
} }
// clean-up
listener.close();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,8 +22,8 @@
*/ */
/* @test /* @test
* @bug 4429043 4493595 6332756 6709457 * @bug 4429043 4493595 6332756 6709457 7146506
* @summary The FileChannel file locking * @summary Test FileChannel file locking
*/ */
import java.io.*; import java.io.*;
@ -33,17 +33,14 @@ import static java.nio.file.StandardOpenOption.*;
/** /**
* Testing FileChannel's lock method. * Testing FileChannel's lock method.
*/ */
public class Lock { public class Lock {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if (args.length > 0) { if (args.length == 2) {
if(args[0].equals("1")) { attemptLock(args[1], args[0].equals("2"));
MadWriter mw = new MadWriter(args[1], false);
} else {
MadWriter mw = new MadWriter(args[1], true);
}
return; return;
} else if (args.length != 0) {
throw new RuntimeException("Wrong number of parameters.");
} }
File blah = File.createTempFile("blah", null); File blah = File.createTempFile("blah", null);
blah.deleteOnExit(); blah.deleteOnExit();
@ -56,120 +53,128 @@ public class Lock {
test2(blah, false); test2(blah, false);
test3(blah); test3(blah);
test4(blah); test4(blah);
blah.delete();
}
private static void test2(File blah, boolean b) throws Exception {
RandomAccessFile raf = new RandomAccessFile(blah, "rw");
FileChannel channel = raf.getChannel();
FileLock lock;
if (b)
lock = channel.lock();
else
lock = channel.tryLock();
lock.release();
channel.close();
} }
/**
* Test mutual locking with other process
*/
static void test1(File blah, String str) throws Exception { static void test1(File blah, String str) throws Exception {
try (RandomAccessFile fis = new RandomAccessFile(blah, "rw")) {
FileChannel fc = fis.getChannel();
FileLock lock = null;
// Grab the lock // grab the lock
RandomAccessFile fis = new RandomAccessFile(blah, "rw"); if (str.equals("1")) {
FileChannel fc = fis.getChannel(); lock = fc.lock(0, 10, false);
FileLock lock = null; if (lock == null)
throw new RuntimeException("Lock should not return null");
if (str.equals("1")) { try {
lock = fc.lock(0, 10, false); fc.lock(5, 10, false);
if (lock == null) throw new RuntimeException("Overlapping locks allowed");
throw new RuntimeException("Lock should not return null"); } catch (OverlappingFileLockException e) {} // correct result
try {
FileLock lock2 = fc.lock(5, 10, false);
throw new RuntimeException("Overlapping locks allowed");
} catch (OverlappingFileLockException e) {
// Correct result
} }
}
// Exec the tamperer // execute the tamperer
String command = System.getProperty("java.home") + String command = System.getProperty("java.home") +
File.separator + "bin" + File.separator + "java"; File.separator + "bin" + File.separator + "java";
String testClasses = System.getProperty("test.classes"); String testClasses = System.getProperty("test.classes");
if (testClasses != null) if (testClasses != null)
command += " -cp " + testClasses; command += " -cp " + testClasses;
command += " Lock " + str + " " + blah; command += " Lock " + str + " " + blah;
Process p = Runtime.getRuntime().exec(command); Process p = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader // evaluate System.out of child process
(new InputStreamReader(p.getInputStream())); String s;
boolean hasOutput = false;
String s; InputStreamReader isr;
int count = 0; isr = new InputStreamReader(p.getInputStream());
while ((s = in.readLine()) != null) { BufferedReader br = new BufferedReader(isr);
if (!s.equals("good")) { while ((s = br.readLine()) != null) {
if (File.separatorChar == '/') { // only throw on Unix as windows over NFS fails...
// Fails on windows over NFS... if ((File.separatorChar == '/') && !s.equals("good")) {
throw new RuntimeException("Failed: "+s); throw new RuntimeException("Failed: " + s);
} }
hasOutput = true;
} }
count++;
}
if (count == 0) { // evaluate System.err in case of System.out of child process
in = new BufferedReader(new InputStreamReader(p.getErrorStream())); // was empty
while ((s = in.readLine()) != null) { if (!hasOutput) {
System.err.println("Error output: " + s); isr = new InputStreamReader(p.getErrorStream());
br = new BufferedReader(isr);
if ((s = br.readLine()) != null) {
System.err.println("Error output:");
System.err.println(s);
while ((s = br.readLine()) != null) {
System.err.println(s);
}
}
throw new RuntimeException("Failed, no output");
} }
throw new RuntimeException("Failed, no output");
}
// Clean up // clean up, check multiple releases
if (lock != null) { if (lock != null) {
/* Check multiple releases */ lock.release();
lock.release(); lock.release();
lock.release(); }
} }
fc.close();
fis.close();
} }
// The overlap check for file locks should be JVM-wide /**
private static void test3(File blah) throws Exception { * Basic test for FileChannel.lock() and FileChannel.tryLock()
FileChannel fc1 = new RandomAccessFile(blah, "rw").getChannel(); */
FileChannel fc2 = new RandomAccessFile(blah, "rw").getChannel(); static void test2(File blah, boolean b) throws Exception {
try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) {
// lock via one channel, and then attempt to lock the same file FileChannel channel = raf.getChannel();
// using a second channel FileLock lock;
FileLock fl1 = fc1.lock(); if (b)
try { lock = channel.lock();
fc2.tryLock(); else
throw new RuntimeException("Overlapping locks allowed"); lock = channel.tryLock();
} catch (OverlappingFileLockException x) { lock.release();
} }
try { }
/**
* Test that overlapping file locking is not possible when using different
* FileChannel objects to the same file path
*/
static void test3(File blah) throws Exception {
try (RandomAccessFile raf1 = new RandomAccessFile(blah, "rw");
RandomAccessFile raf2 = new RandomAccessFile(blah, "rw"))
{
FileChannel fc1 = raf1.getChannel();
FileChannel fc2 = raf2.getChannel();
// lock via one channel, and then attempt to lock the same file
// using a second channel
FileLock fl1 = fc1.lock();
try {
fc2.tryLock();
throw new RuntimeException("Overlapping locks allowed");
} catch (OverlappingFileLockException x) {}
try {
fc2.lock();
throw new RuntimeException("Overlapping locks allowed");
} catch (OverlappingFileLockException x) {}
// release lock and the attempt to lock with the second channel
// should succeed.
fl1.release();
fc2.lock(); fc2.lock();
throw new RuntimeException("Overlapping locks allowed"); try {
} catch (OverlappingFileLockException x) { fc1.lock();
throw new RuntimeException("Overlapping locks allowed");
} catch (OverlappingFileLockException x) {}
} }
// release lock and the attempt to lock with the second channel
// should succeed.
fl1.release();
FileLock fl2 = fc2.lock();
try {
fc1.lock();
throw new RuntimeException("Overlapping locks allowed");
} catch (OverlappingFileLockException x) {
}
fc1.close();
fc2.close();
} }
/** /**
* Test file locking when file is opened for append * Test file locking when file is opened for append
*/ */
static void test4(File blah) throws Exception { static void test4(File blah) throws Exception {
try (FileChannel fc = new FileOutputStream(blah, true).getChannel()) { try (FileOutputStream fos = new FileOutputStream(blah, true)) {
FileChannel fc = fos.getChannel();
fc.tryLock().release(); fc.tryLock().release();
fc.tryLock(0L, 1L, false).release(); fc.tryLock(0L, 1L, false).release();
fc.lock().release(); fc.lock().release();
@ -182,30 +187,31 @@ public class Lock {
fc.lock(0L, 1L, false).release(); fc.lock(0L, 1L, false).release();
} }
} }
}
class MadWriter { /**
public MadWriter(String s, boolean b) throws Exception { * Utility method to be run in secondary process which tries to acquire a
File f = new File(s); * lock on a FileChannel
RandomAccessFile fos = new RandomAccessFile(f, "rw"); */
FileChannel fc = fos.getChannel(); static void attemptLock(String fileName,
if (fc.tryLock(10, 10, false) == null) { boolean expectsLock) throws Exception
System.out.println("bad: Failed to grab adjacent lock"); {
File f = new File(fileName);
try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) {
FileChannel fc = raf.getChannel();
if (fc.tryLock(10, 10, false) == null) {
System.out.println("bad: Failed to grab adjacent lock");
}
if (fc.tryLock(0, 10, false) == null) {
if (expectsLock)
System.out.println("bad");
else
System.out.println("good");
} else {
if (expectsLock)
System.out.println("good");
else
System.out.println("bad");
}
} }
FileLock lock = fc.tryLock(0, 10, false);
if (lock == null) {
if (b)
System.out.println("bad");
else
System.out.println("good");
} else {
if (b)
System.out.println("good");
else
System.out.println("bad");
}
fc.close();
fos.close();
} }
} }

View File

@ -95,7 +95,7 @@ public class Basic {
return 0; return 0;
} }
static int checkContentTypes(String[] extensions, String[][] expectedTypes) static int checkContentTypes(String[] extensions, String[] expectedTypes)
throws IOException { throws IOException {
if (extensions.length != expectedTypes.length) { if (extensions.length != expectedTypes.length) {
System.err.println("Parameter array lengths differ"); System.err.println("Parameter array lengths differ");
@ -112,27 +112,10 @@ public class Basic {
System.err.println("Content type of " + extension System.err.println("Content type of " + extension
+ " cannot be determined"); + " cannot be determined");
failures++; failures++;
} else { } else if (!type.equals(expectedTypes[i])) {
boolean isTypeFound = false; System.err.printf("Content type: %s; expected: %s%n",
for (String s : expectedTypes[i]) { type, expectedTypes);
if (type.equals(s)) { failures++;
isTypeFound = true;
break;
}
}
if (!isTypeFound) {
System.err.printf("Content type: %s; expected: ", type);
int j = 0;
for (String s : expectedTypes[i]) {
if (j++ == 0) {
System.err.printf("%s", s);
} else {
System.err.printf(", or %s", s);
}
}
System.err.println();
failures++;
}
} }
} finally { } finally {
Files.delete(file); Files.delete(file);
@ -174,8 +157,6 @@ public class Basic {
// Verify that certain media extensions are mapped to the correct type. // Verify that certain media extensions are mapped to the correct type.
String[] extensions = new String[]{ String[] extensions = new String[]{
"aac",
"flac",
"jpg", "jpg",
"mp3", "mp3",
"mp4", "mp4",
@ -183,15 +164,13 @@ public class Basic {
"png", "png",
"webm" "webm"
}; };
String[][] expectedTypes = new String[][] { String[] expectedTypes = new String[] {
{"audio/aac", "audio/x-aac", "audio/vnd.dlna.adts"}, "image/jpeg",
{"audio/flac", "audio/x-flac"}, "audio/mpeg",
{"image/jpeg"}, "video/mp4",
{"audio/mpeg"}, "application/pdf",
{"video/mp4"}, "image/png",
{"application/pdf"}, "video/webm"
{"image/png"},
{"video/webm"}
}; };
failures += checkContentTypes(extensions, expectedTypes); failures += checkContentTypes(extensions, expectedTypes);

File diff suppressed because it is too large Load Diff

View File

@ -53,10 +53,11 @@ public class LotsOfCancels {
Path testDir = Paths.get(System.getProperty("test.dir", ".")); Path testDir = Paths.get(System.getProperty("test.dir", "."));
Path top = Files.createTempDirectory(testDir, "LotsOfCancels"); Path top = Files.createTempDirectory(testDir, "LotsOfCancels");
for (int i=1; i<=16; i++) { for (int i=1; i<=16; i++) {
int id = i;
Path dir = Files.createDirectory(top.resolve("dir-" + i)); Path dir = Files.createDirectory(top.resolve("dir-" + i));
WatchService watcher = FileSystems.getDefault().newWatchService(); WatchService watcher = FileSystems.getDefault().newWatchService();
pool.submit(() -> handle(dir, watcher)); pool.submit(() -> handle(id, dir, watcher));
pool.submit(() -> poll(watcher)); pool.submit(() -> poll(id, watcher));
} }
} finally { } finally {
pool.shutdown(); pool.shutdown();
@ -74,7 +75,8 @@ public class LotsOfCancels {
* Stress the given WatchService, specifically the cancel method, in * Stress the given WatchService, specifically the cancel method, in
* the given directory. Closes the WatchService when done. * the given directory. Closes the WatchService when done.
*/ */
static void handle(Path dir, WatchService watcher) { static void handle(int id, Path dir, WatchService watcher) {
System.out.printf("begin handle %d%n", id);
try { try {
try { try {
Path file = dir.resolve("anyfile"); Path file = dir.resolve("anyfile");
@ -85,12 +87,15 @@ public class LotsOfCancels {
key.cancel(); key.cancel();
} }
} finally { } finally {
System.out.printf("WatchService %d closing ...%n", id);
watcher.close(); watcher.close();
System.out.printf("WatchService %d closed %n", id);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
failed = true; failed = true;
} }
System.out.printf("end handle %d%n", id);
} }
/** /**
@ -98,7 +103,8 @@ public class LotsOfCancels {
* queue drained, it also hogs a CPU core which seems necessary to * queue drained, it also hogs a CPU core which seems necessary to
* tickle the original bug. * tickle the original bug.
*/ */
static void poll(WatchService watcher) { static void poll(int id, WatchService watcher) {
System.out.printf("begin poll %d%n", id);
try { try {
for (;;) { for (;;) {
WatchKey key = watcher.take(); WatchKey key = watcher.take();
@ -108,10 +114,12 @@ public class LotsOfCancels {
} }
} }
} catch (ClosedWatchServiceException expected) { } catch (ClosedWatchServiceException expected) {
// nothing to do // nothing to do but print
System.out.printf("poll %d expected exception %s%n", id, expected);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
failed = true; failed = true;
} }
System.out.printf("end poll %d%n", id);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,9 @@ import java.util.concurrent.TimeUnit;
import static java.nio.file.StandardWatchEventKinds.*; import static java.nio.file.StandardWatchEventKinds.*;
public class UpdateInterference { public class UpdateInterference {
private static volatile boolean stop;
public static void main(String[] args) throws IOException, InterruptedException { public static void main(String[] args) throws IOException, InterruptedException {
final Path root = Files.createTempDirectory("test"); final Path root = Files.createTempDirectory("test");
final Path foo = root.resolve("foo"); final Path foo = root.resolve("foo");
@ -43,64 +46,89 @@ public class UpdateInterference {
Files.createDirectory(bar); Files.createDirectory(bar);
Files.createDirectory(baz); Files.createDirectory(baz);
final WatchService watcher = root.getFileSystem().newWatchService(); try (final WatchService watcher = root.getFileSystem().newWatchService()) {
final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE); final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE);
final WatchKey barKey = bar.register(watcher, ENTRY_CREATE); final WatchKey barKey = bar.register(watcher, ENTRY_CREATE);
new Thread() { Thread t1 = null;
{ setDaemon(true); } Thread t2 = null;
try {
t1 = new Thread() {
@Override @Override
public void run() { public void run() {
while (true) { while (!stop) {
try { try {
final Path temp = Files.createTempFile(foo, "temp", ".tmp"); final Path temp = Files.createTempFile(foo, "temp", ".tmp");
Files.delete(temp); Files.delete(temp);
Thread.sleep(10); Thread.sleep(10);
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}
}
}.start();
new Thread() {
{ setDaemon(true); }
@Override
public void run() {
WatchKey bazKeys[] = new WatchKey[32];
while (true) {
try {
for( int i = 0; i < bazKeys.length; i++) {
bazKeys[i] = baz.register(watcher, ENTRY_CREATE);
} }
for( int i = 0; i < bazKeys.length; i++) {
bazKeys[i].cancel();
}
Thread.sleep(1);
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
} }
};
t2 = new Thread() {
@Override
public void run() {
WatchKey bazKeys[] = new WatchKey[32];
while (!stop) {
try {
for( int i = 0; i < bazKeys.length; i++) {
bazKeys[i] = baz.register(watcher, ENTRY_CREATE);
}
for( int i = 0; i < bazKeys.length; i++) {
bazKeys[i].cancel();
}
Thread.sleep(1);
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
};
t1.start();
t2.start();
long time = System.currentTimeMillis();
while ((System.currentTimeMillis() - time) < 15000) {
final WatchKey key = watcher.poll(60, TimeUnit.SECONDS);
if (key == null) continue;
if (key != fooKey) {
List<WatchEvent<?>> pollEvents = key.pollEvents();
for (WatchEvent<?> watchEvent : pollEvents) {
System.out.println(watchEvent.count() + " " +
watchEvent.kind() + " " +
watchEvent.context());
}
throw new RuntimeException("Event received for unexpected key");
}
key.reset();
}
} finally {
// the threads should stop before WatchService is closed
// to avoid ClosedWatchServiceException
stop = true;
// wait for threads to finish
if (t1 != null) {
t1.join();
}
if (t2 != null) {
t2.join();
} }
} }
}.start(); } finally {
// clean up
long time = System.currentTimeMillis(); Files.delete(foo);
while ((System.currentTimeMillis() - time) < 15000) { Files.delete(bar);
final WatchKey key = watcher.poll(60, TimeUnit.SECONDS); Files.delete(baz);
if (key == null) continue; Files.delete(root);
if (key != fooKey) {
List<WatchEvent<?>> pollEvents = key.pollEvents();
for (WatchEvent<?> watchEvent : pollEvents) {
System.out.println(watchEvent.count() + " " +
watchEvent.kind() + " " +
watchEvent.context());
}
throw new RuntimeException("Event received for unexpected key");
}
key.reset();
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -419,6 +419,21 @@ public class TCKZoneOffset extends AbstractDateTimeTest {
ZoneOffset.ofHoursMinutesSeconds(-19, 0, 0); ZoneOffset.ofHoursMinutesSeconds(-19, 0, 0);
} }
@Test(expectedExceptions=DateTimeException.class)
public void test_factory_int_hours_minutes_seconds_minutesMinValue() {
ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, -1);
}
@Test(expectedExceptions=DateTimeException.class)
public void test_factory_int_hours_minutes_seconds_secondsMinValue() {
ZoneOffset.ofHoursMinutesSeconds(0, 0, Integer.MIN_VALUE);
}
@Test(expectedExceptions=DateTimeException.class)
public void test_factory_int_hours_minutes_seconds_minutesAndSecondsMinValue() {
ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, Integer.MIN_VALUE);
}
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@Test @Test
public void test_factory_ofTotalSeconds() { public void test_factory_ofTotalSeconds() {
@ -437,6 +452,11 @@ public class TCKZoneOffset extends AbstractDateTimeTest {
ZoneOffset.ofTotalSeconds(-18 * 60 * 60 - 1); ZoneOffset.ofTotalSeconds(-18 * 60 * 60 - 1);
} }
@Test(expectedExceptions=DateTimeException.class)
public void test_factory_ofTotalSeconds_minValue() {
ZoneOffset.ofTotalSeconds(Integer.MIN_VALUE);
}
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// from() // from()
//----------------------------------------------------------------------- //-----------------------------------------------------------------------

View File

@ -359,6 +359,21 @@ public class ConcurrentHashMapTest extends JSR166TestCase {
assertTrue(s.contains(five)); assertTrue(s.contains(five));
} }
/**
* Test keySet().removeAll on empty map
*/
public void testKeySet_empty_removeAll() {
ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
Set<Integer> set = map.keySet();
set.removeAll(Collections.emptyList());
assertTrue(map.isEmpty());
assertTrue(set.isEmpty());
// following is test for JDK-8163353
set.removeAll(Collections.emptySet());
assertTrue(map.isEmpty());
assertTrue(set.isEmpty());
}
/** /**
* keySet.toArray returns contains all keys * keySet.toArray returns contains all keys
*/ */

View File

@ -80,7 +80,7 @@ public class MultiReleaseJarAPI {
} }
try (JarFile jf = new JarFile(multirelease)) { try (JarFile jf = new JarFile(multirelease)) {
Assert.assertFalse(jf.isMultiRelease()); Assert.assertTrue(jf.isMultiRelease());
} }
try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Runtime.version())) { try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Runtime.version())) {

View 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!");
}
}

View 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");
}
}
}

View File

@ -3,4 +3,4 @@
TestNG.dirs = . TestNG.dirs = .
javatest.maxOutputSize = 250000 javatest.maxOutputSize = 250000
modules = jdk.compiler modules = jdk.compiler jdk.zipfs

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
* @summary Verify the defining class loader of each module never delegates * @summary Verify the defining class loader of each module never delegates
* to its child class loader. Also sanity check java.compact2 * to its child class loader. Also sanity check java.compact2
* requires. * requires.
* @modules java.compact2
* @run testng/othervm --add-modules=ALL-SYSTEM VerifyModuleDelegation * @run testng/othervm --add-modules=ALL-SYSTEM VerifyModuleDelegation
*/ */
@ -33,7 +34,9 @@ import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder; import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference; import java.lang.module.ModuleReference;
import java.lang.reflect.Layer; import java.lang.reflect.Layer;
import java.lang.reflect.Module;
import java.util.Set; import java.util.Set;
import static java.util.stream.Collectors.toSet;
import static java.lang.module.ModuleDescriptor.Requires.Modifier.*; import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
@ -58,8 +61,9 @@ public class VerifyModuleDelegation {
.requires(Set.of(PUBLIC), "java.xml") .requires(Set.of(PUBLIC), "java.xml")
.build(); .build();
private static final Set<ModuleReference> MREFS private static final Set<ModuleDescriptor> MREFS
= ModuleFinder.ofSystem().findAll(); = Layer.boot().modules().stream().map(Module::getDescriptor)
.collect(toSet());
private void check(ModuleDescriptor md, ModuleDescriptor ref) { private void check(ModuleDescriptor md, ModuleDescriptor ref) {
assertTrue(md.requires().size() == ref.requires().size()); assertTrue(md.requires().size() == ref.requires().size());
@ -69,7 +73,7 @@ public class VerifyModuleDelegation {
@Test @Test
public void checkJavaBase() { public void checkJavaBase() {
ModuleDescriptor md = ModuleDescriptor md =
MREFS.stream().map(ModuleReference::descriptor) MREFS.stream()
.filter(d -> d.name().equals(JAVA_BASE)) .filter(d -> d.name().equals(JAVA_BASE))
.findFirst().orElseThrow(Error::new); .findFirst().orElseThrow(Error::new);
@ -78,7 +82,7 @@ public class VerifyModuleDelegation {
@Test @Test
public void checkCompact2() { public void checkCompact2() {
ModuleDescriptor md = ModuleDescriptor md =
MREFS.stream().map(ModuleReference::descriptor) MREFS.stream()
.filter(d -> d.name().equals(JAVA_COMPACT2)) .filter(d -> d.name().equals(JAVA_COMPACT2))
.findFirst().orElseThrow(Error::new); .findFirst().orElseThrow(Error::new);
check(md, COMPACT2); check(md, COMPACT2);
@ -87,7 +91,7 @@ public class VerifyModuleDelegation {
@Test @Test
public void checkLoaderDelegation() { public void checkLoaderDelegation() {
Layer boot = Layer.boot(); Layer boot = Layer.boot();
MREFS.stream().map(ModuleReference::descriptor) MREFS.stream()
.forEach(md -> md.requires().stream().forEach(req -> .forEach(md -> md.requires().stream().forEach(req ->
{ {
// check if M requires D and D's loader must be either the // check if M requires D and D's loader must be either the

Some files were not shown because too many files have changed in this diff Show More