This commit is contained in:
J. Duke 2017-07-05 22:08:33 +02:00
commit b7dfcd0b16
132 changed files with 4384 additions and 1532 deletions

View File

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

View File

@ -375,3 +375,4 @@ c3e83ccab3bb1733ae903d681879a33f85ed465c jdk-9+129
77f9692d5976ae155773dd3e07533616bb95bae1 jdk-9+130
f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131
1ab4b9399c4cba584f66c1c088188f2f565fbf9c jdk-9+132
2021bfedf1c478a4808a7711a6090682a12f4c0e jdk-9+133

View File

@ -535,3 +535,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130
943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131
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);
}
double G1Analytics::oldest_known_gc_end_time_sec() const {
return _recent_prev_end_times_for_all_gcs_sec->oldest();
}
double G1Analytics::last_known_gc_end_time_sec() const {
return _recent_prev_end_times_for_all_gcs_sec->last();
return _recent_prev_end_times_for_all_gcs_sec->oldest();
}
void G1Analytics::update_recent_gc_times(double end_time_sec,

View File

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

View File

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

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);
double interval_ms =
(end_time_sec - _analytics->oldest_known_gc_end_time_sec()) * 1000.0;
(end_time_sec - _analytics->last_known_gc_end_time_sec()) * 1000.0;
_analytics->update_recent_gc_times(end_time_sec, pause_time_ms);
_analytics->compute_pause_time_ratio(interval_ms, pause_time_ms);
}

View File

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

View File

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

View File

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

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 \
-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.
#
# This code is free software; you can redistribute it and/or modify it
@ -38,8 +38,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
$(LIBJAVA_HEADER_FLAGS) \
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.pkcs11, \
DISABLED_WARNINGS_solstudio := E_DECLARATION_IN_CODE, \
DISABLED_WARNINGS_microsoft := 4013 4267, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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.
*
* This code is free software; you can redistribute it and/or modify it
@ -233,7 +233,7 @@ public final class HttpCookie implements Cloneable {
// if not specify max-age, this cookie should be
// discarded when user agent is to be closed, but
// it is not expired.
if (maxAge == MAX_AGE_UNSPECIFIED) return false;
if (maxAge < 0) return false;
long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000;
if (deltaSecond > maxAge)
@ -952,7 +952,8 @@ public final class HttpCookie implements Cloneable {
String attrName,
String attrValue) {
if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED) {
cookie.setMaxAge(cookie.expiryDate2DeltaSeconds(attrValue));
long delta = cookie.expiryDate2DeltaSeconds(attrValue);
cookie.setMaxAge(delta > 0 ? delta : 0);
}
}
});

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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 {
// There is no restriction to any algorithms.
permission javax.crypto.CryptoAllPermission;

View File

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

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.
grant {
// There is no restriction to any algorithms.
permission javax.crypto.CryptoAllPermission;

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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);
tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
if (tmpBuffer.length > outLen) {
throw new BadPaddingException("Output buffer too small");
throw new BadPaddingException(
"Output buffer (" + outLen + ") is too small to " +
"hold the produced data (" + tmpBuffer.length + ")");
}
System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
n = tmpBuffer.length;

View File

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

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.
*
* This code is free software; you can redistribute it and/or modify it
@ -49,6 +49,7 @@ void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
(JNIEnv *env, jclass thisClass, jstring jLibName)
{
void *hModule;
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
if (libName == NULL) {
return 0L;
@ -56,9 +57,9 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
// look up existing handle only, do not load
#if defined(AIX)
void *hModule = dlopen(libName, RTLD_LAZY);
hModule = dlopen(libName, RTLD_LAZY);
#else
void *hModule = dlopen(libName, RTLD_NOLOAD);
hModule = dlopen(libName, RTLD_NOLOAD);
#endif
dprintf2("-handle for %s: %u\n", libName, hModule);
(*env)->ReleaseStringUTFChars(env, jLibName, libName);

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

@ -165,8 +165,8 @@ class JarFileSystem extends ZipFileSystem {
walk(inode.child, process);
} else {
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
java/lang/StringCoding/CheckEncodings.sh 7008363 generic-all
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java 8160690 generic-all
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java 8160690 generic-all
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java 8160690 generic-all
java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java 8160690 generic-all
############################################################################
@ -211,8 +207,6 @@ sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic-
java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all
sun/rmi/runtime/Log/6409194/NoConsoleOutput.java 8164124 windows-all
############################################################################
# jdk_security

View File

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

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

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

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

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

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

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

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

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.
*
* This code is free software; you can redistribute it and/or modify it
@ -419,6 +419,21 @@ public class TCKZoneOffset extends AbstractDateTimeTest {
ZoneOffset.ofHoursMinutesSeconds(-19, 0, 0);
}
@Test(expectedExceptions=DateTimeException.class)
public void test_factory_int_hours_minutes_seconds_minutesMinValue() {
ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, -1);
}
@Test(expectedExceptions=DateTimeException.class)
public void test_factory_int_hours_minutes_seconds_secondsMinValue() {
ZoneOffset.ofHoursMinutesSeconds(0, 0, Integer.MIN_VALUE);
}
@Test(expectedExceptions=DateTimeException.class)
public void test_factory_int_hours_minutes_seconds_minutesAndSecondsMinValue() {
ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, Integer.MIN_VALUE);
}
//-----------------------------------------------------------------------
@Test
public void test_factory_ofTotalSeconds() {
@ -437,6 +452,11 @@ public class TCKZoneOffset extends AbstractDateTimeTest {
ZoneOffset.ofTotalSeconds(-18 * 60 * 60 - 1);
}
@Test(expectedExceptions=DateTimeException.class)
public void test_factory_ofTotalSeconds_minValue() {
ZoneOffset.ofTotalSeconds(Integer.MIN_VALUE);
}
//-----------------------------------------------------------------------
// from()
//-----------------------------------------------------------------------

View File

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

View File

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

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 = .
javatest.maxOutputSize = 250000
modules = jdk.compiler
modules = jdk.compiler jdk.zipfs

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