changeset 16677:68cb676e526a

Merge
author lana
date Thu, 09 Feb 2017 18:10:19 +0000
parents 847d7a6aef45 a547b3736c3b
children 34174308ee40
files src/java.base/share/classes/sun/security/provider/certpath/PKIXTimestampParameters.java src/java.base/share/classes/sun/security/util/CertConstraintParameters.java test/java/lang/invoke/lambda/MetafactorySamReturnTest.java
diffstat 63 files changed, 3797 insertions(+), 1022 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/StackStreamFactory.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/java/lang/StackStreamFactory.java	Thu Feb 09 18:10:19 2017 +0000
@@ -25,11 +25,13 @@
 package java.lang;
 
 import jdk.internal.reflect.MethodAccessor;
+import jdk.internal.reflect.ConstructorAccessor;
 import java.lang.StackWalker.Option;
 import java.lang.StackWalker.StackFrame;
 
 import java.lang.annotation.Native;
 import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
 import java.util.HashSet;
 import java.util.NoSuchElementException;
 import java.util.Objects;
@@ -922,7 +924,8 @@
          */
         final void setBatch(int depth, int startIndex, int endIndex) {
             if (startIndex <= 0 || endIndex <= 0)
-                throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex);
+                throw new IllegalArgumentException("startIndex=" + startIndex
+                        + " endIndex=" + endIndex);
 
             this.origin = startIndex;
             this.fence = endIndex;
@@ -980,13 +983,18 @@
 
     private static boolean isReflectionFrame(Class<?> c) {
         if (c.getName().startsWith("jdk.internal.reflect") &&
-                !MethodAccessor.class.isAssignableFrom(c)) {
-            throw new InternalError("Not jdk.internal.reflect.MethodAccessor: " + c.toString());
+                !MethodAccessor.class.isAssignableFrom(c) &&
+                !ConstructorAccessor.class.isAssignableFrom(c)) {
+            throw new InternalError("Not jdk.internal.reflect.MethodAccessor"
+                    + " or jdk.internal.reflect.ConstructorAccessor: "
+                    + c.toString());
         }
         // ## should filter all @Hidden frames?
         return c == Method.class ||
-                MethodAccessor.class.isAssignableFrom(c) ||
-                c.getName().startsWith("java.lang.invoke.LambdaForm");
+               c == Constructor.class ||
+               MethodAccessor.class.isAssignableFrom(c) ||
+               ConstructorAccessor.class.isAssignableFrom(c) ||
+               c.getName().startsWith("java.lang.invoke.LambdaForm");
     }
 
 }
--- a/src/java.base/share/classes/java/lang/StackWalker.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/java/lang/StackWalker.java	Thu Feb 09 18:10:19 2017 +0000
@@ -29,6 +29,7 @@
 import java.util.*;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.function.Predicate;
 import java.util.stream.Stream;
 
 /**
@@ -207,13 +208,23 @@
         /**
          * Shows all reflection frames.
          *
-         * <p>By default, reflection frames are hidden.  This includes the
-         * {@link java.lang.reflect.Method#invoke} method
-         * and the reflection implementation classes. A {@code StackWalker} with
-         * this {@code SHOW_REFLECT_FRAMES} option will show all reflection frames.
-         * The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
+         * <p>By default, reflection frames are hidden.  A {@code StackWalker}
+         * configured with this {@code SHOW_REFLECT_FRAMES} option
+         * will show all reflection frames that
+         * include {@link java.lang.reflect.Method#invoke} and
+         * {@link java.lang.reflect.Constructor#newInstance(Object...)}
+         * and their reflection implementation classes.
+         *
+         * <p>The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
          * reflection frames and it will also show other hidden frames that
          * are implementation-specific.
+         *
+         * @apiNote
+         * This option includes the stack frames representing the invocation of
+         * {@code Method} and {@code Constructor}.  Any utility methods that
+         * are equivalent to calling {@code Method.invoke} or
+         * {@code Constructor.newInstance} such as {@code Class.newInstance}
+         * are not filtered or controlled by any stack walking option.
          */
         SHOW_REFLECT_FRAMES,
         /**
@@ -468,8 +479,9 @@
      * Gets the {@code Class} object of the caller invoking the method
      * that calls this {@code getCallerClass} method.
      *
-     * <p> Reflection frames, {@link java.lang.invoke.MethodHandle}, and
-     * hidden frames are filtered regardless of the
+     * <p> This method filters {@linkplain Option#SHOW_REFLECT_FRAMES reflection
+     * frames}, {@link java.lang.invoke.MethodHandle}, and
+     * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} regardless of the
      * {@link Option#SHOW_REFLECT_FRAMES SHOW_REFLECT_FRAMES}
      * and {@link Option#SHOW_HIDDEN_FRAMES SHOW_HIDDEN_FRAMES} options
      * this {@code StackWalker} has been configured with.
--- a/src/java.base/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Thu Feb 09 18:10:19 2017 +0000
@@ -141,6 +141,18 @@
         this.markerInterfaces = markerInterfaces;
         this.additionalBridges = additionalBridges;
 
+        if (samMethodName.isEmpty() ||
+                samMethodName.indexOf('.') >= 0 ||
+                samMethodName.indexOf(';') >= 0 ||
+                samMethodName.indexOf('[') >= 0 ||
+                samMethodName.indexOf('/') >= 0 ||
+                samMethodName.indexOf('<') >= 0 ||
+                samMethodName.indexOf('>') >= 0) {
+            throw new LambdaConversionException(String.format(
+                    "Method name '%s' is not legal",
+                    samMethodName));
+        }
+
         if (!samBase.isInterface()) {
             throw new LambdaConversionException(String.format(
                     "Functional interface %s is not an interface",
@@ -275,25 +287,39 @@
                 (implKind == MethodHandleInfo.REF_newInvokeSpecial)
                   ? implDefiningClass
                   : implMethodType.returnType();
-        Class<?> samReturnType = samMethodType.returnType();
         if (!isAdaptableToAsReturn(actualReturnType, expectedType)) {
             throw new LambdaConversionException(
                     String.format("Type mismatch for lambda return: %s is not convertible to %s",
                                   actualReturnType, expectedType));
         }
-        if (!isAdaptableToAsReturnStrict(expectedType, samReturnType)) {
-            throw new LambdaConversionException(
-                    String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
-                                  expectedType, samReturnType));
+
+        // Check descriptors of generated methods
+        checkDescriptor(samMethodType);
+        for (MethodType bridgeMT : additionalBridges) {
+            checkDescriptor(bridgeMT);
         }
-        for (MethodType bridgeMT : additionalBridges) {
-            if (!isAdaptableToAsReturnStrict(expectedType, bridgeMT.returnType())) {
-                throw new LambdaConversionException(
-                        String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
-                                      expectedType, bridgeMT.returnType()));
+    }
+
+    /** Validate that the given descriptor's types are compatible with {@code instantiatedMethodType} **/
+    private void checkDescriptor(MethodType descriptor) throws LambdaConversionException {
+        for (int i = 0; i < instantiatedMethodType.parameterCount(); i++) {
+            Class<?> instantiatedParamType = instantiatedMethodType.parameterType(i);
+            Class<?> descriptorParamType = descriptor.parameterType(i);
+            if (!descriptorParamType.isAssignableFrom(instantiatedParamType)) {
+                String msg = String.format("Type mismatch for instantiated parameter %d: %s is not a subtype of %s",
+                                           i, instantiatedParamType, descriptorParamType);
+                throw new LambdaConversionException(msg);
             }
         }
-     }
+
+        Class<?> instantiatedReturnType = instantiatedMethodType.returnType();
+        Class<?> descriptorReturnType = descriptor.returnType();
+        if (!isAdaptableToAsReturnStrict(instantiatedReturnType, descriptorReturnType)) {
+            String msg = String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
+                                       instantiatedReturnType, descriptorReturnType);
+            throw new LambdaConversionException(msg);
+        }
+    }
 
     /**
      * Check type adaptability for parameter types.
@@ -345,8 +371,8 @@
                || !fromType.equals(void.class) && isAdaptableTo(fromType, toType, false);
     }
     private boolean isAdaptableToAsReturnStrict(Class<?> fromType, Class<?> toType) {
-        if (fromType.equals(void.class)) return toType.equals(void.class);
-        return isAdaptableTo(fromType, toType, true);
+        if (fromType.equals(void.class) || toType.equals(void.class)) return fromType.equals(toType);
+        else return isAdaptableTo(fromType, toType, true);
     }
 
 
--- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Thu Feb 09 18:10:19 2017 +0000
@@ -591,8 +591,8 @@
                 c = Class.forName(m, cn);
             }
         } catch (LinkageError le) {
-            abort(null, "java.launcher.module.error3",
-                    mainClass, m.getName(), le.getLocalizedMessage());
+            abort(null, "java.launcher.module.error3", mainClass, m.getName(),
+                    le.getClass().getName() + ": " + le.getLocalizedMessage());
         }
         if (c == null) {
             abort(null, "java.launcher.module.error2", mainClass, mainModule);
@@ -645,7 +645,8 @@
                 }
             }
         } catch (LinkageError le) {
-            abort(le, "java.launcher.cls.error6", cn, le.getLocalizedMessage());
+            abort(le, "java.launcher.cls.error6", cn,
+                    le.getClass().getName() + ": " + le.getLocalizedMessage());
         }
         return mainClass;
     }
--- a/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 import java.security.Signature;
 import java.security.SignatureException;
 import java.security.Timestamp;
+import java.security.cert.CertPathValidatorException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CertPath;
@@ -48,6 +49,7 @@
 import java.util.Set;
 
 import sun.security.timestamp.TimestampToken;
+import sun.security.util.ConstraintsParameters;
 import sun.security.util.Debug;
 import sun.security.util.DerEncoder;
 import sun.security.util.DerInputStream;
@@ -321,6 +323,8 @@
                 data = content.getContentBytes();
             }
 
+            ConstraintsParameters cparams =
+                    new ConstraintsParameters(timestamp);
             String digestAlgname = getDigestAlgorithmId().getName();
 
             byte[] dataSigned;
@@ -347,11 +351,11 @@
                 if (messageDigest == null) // fail if there is no message digest
                     return null;
 
-                // check that algorithm is not restricted
-                if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET,
-                        digestAlgname, null)) {
-                    throw new SignatureException("Digest check failed. " +
-                            "Disabled algorithm used: " + digestAlgname);
+                // check that digest algorithm is not restricted
+                try {
+                    JAR_DISABLED_CHECK.permits(digestAlgname, cparams);
+                } catch (CertPathValidatorException e) {
+                    throw new SignatureException(e.getMessage(), e);
                 }
 
                 MessageDigest md = MessageDigest.getInstance(digestAlgname);
@@ -385,17 +389,18 @@
             String algname = AlgorithmId.makeSigAlg(
                     digestAlgname, encryptionAlgname);
 
-            // check that algorithm is not restricted
-            if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, algname, null)) {
-                throw new SignatureException("Signature check failed. " +
-                        "Disabled algorithm used: " + algname);
+            // check that jar signature algorithm is not restricted
+            try {
+                JAR_DISABLED_CHECK.permits(algname, cparams);
+            } catch (CertPathValidatorException e) {
+                throw new SignatureException(e.getMessage(), e);
             }
 
             X509Certificate cert = getCertificate(block);
-            PublicKey key = cert.getPublicKey();
             if (cert == null) {
                 return null;
             }
+            PublicKey key = cert.getPublicKey();
 
             // check if the public key is restricted
             if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
--- a/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 import java.security.AlgorithmConstraints;
 import java.security.CryptoPrimitive;
 import java.security.Timestamp;
+import java.security.cert.CertPathValidator;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -53,9 +54,10 @@
 import java.security.spec.DSAPublicKeySpec;
 
 import sun.security.util.AnchorCertificates;
-import sun.security.util.CertConstraintParameters;
+import sun.security.util.ConstraintsParameters;
 import sun.security.util.Debug;
 import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.validator.Validator;
 import sun.security.x509.X509CertImpl;
 import sun.security.x509.X509CRLImpl;
 import sun.security.x509.AlgorithmId;
@@ -79,6 +81,7 @@
     private final Date pkixdate;
     private PublicKey prevPubKey;
     private final Timestamp jarTimestamp;
+    private final String variant;
 
     private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
         Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
@@ -109,64 +112,36 @@
      *
      * @param anchor the trust anchor selected to validate the target
      *     certificate
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    public AlgorithmChecker(TrustAnchor anchor) {
-        this(anchor, certPathDefaultConstraints, null);
-    }
-
-    /**
-     * Create a new {@code AlgorithmChecker} with the
-     * given {@code TrustAnchor} and {@code AlgorithmConstraints}.
-     *
-     * @param anchor the trust anchor selected to validate the target
-     *     certificate
-     * @param constraints the algorithm constraints (or null)
-     *
-     * @throws IllegalArgumentException if the {@code anchor} is null
-     */
-    public AlgorithmChecker(TrustAnchor anchor,
-            AlgorithmConstraints constraints) {
-        this(anchor, constraints, null);
-    }
-
-    /**
-     * Create a new {@code AlgorithmChecker} with the
-     * given {@code AlgorithmConstraints}.
-     * <p>
-     * Note that this constructor will be used to check a certification
-     * path where the trust anchor is unknown, or a certificate list which may
-     * contain the trust anchor. This constructor is used by SunJSSE.
-     *
-     * @param constraints the algorithm constraints (or null)
-     */
-    public AlgorithmChecker(AlgorithmConstraints constraints) {
-        this.prevPubKey = null;
-        this.trustedPubKey = null;
-        this.constraints = constraints;
-        this.pkixdate = null;
-        this.jarTimestamp = null;
+    public AlgorithmChecker(TrustAnchor anchor, String variant) {
+        this(anchor, certPathDefaultConstraints, null, variant);
     }
 
     /**
      * Create a new {@code AlgorithmChecker} with the given
-     * {@code Timestamp}.
+     * {@code AlgorithmConstraints}, {@code Timestamp}, and/or {@code Variant}.
      * <p>
-     * Note that this constructor will be used to check a certification
-     * path for signed JAR files that are timestamped.
+     * Note that this constructor can initialize a variation of situations where
+     * the AlgorithmConstraints, Timestamp, or Variant maybe known.
      *
+     * @param constraints the algorithm constraints (or null)
      * @param jarTimestamp Timestamp passed for JAR timestamp constraint
      *                     checking. Set to null if not applicable.
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    public AlgorithmChecker(Timestamp jarTimestamp) {
+    public AlgorithmChecker(AlgorithmConstraints constraints,
+            Timestamp jarTimestamp, String variant) {
         this.prevPubKey = null;
         this.trustedPubKey = null;
-        this.constraints = certPathDefaultConstraints;
-        if (jarTimestamp == null) {
-            throw new IllegalArgumentException(
-                    "Timestamp cannot be null");
-        }
-        this.pkixdate = jarTimestamp.getTimestamp();
+        this.constraints = (constraints == null ? certPathDefaultConstraints :
+                constraints);
+        this.pkixdate = (jarTimestamp != null ? jarTimestamp.getTimestamp() :
+                null);
         this.jarTimestamp = jarTimestamp;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
     }
 
     /**
@@ -178,12 +153,13 @@
      * @param constraints the algorithm constraints (or null)
      * @param pkixdate Date the constraints are checked against. The value is
      *             either the PKIXParameter date or null for the current date.
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      *
      * @throws IllegalArgumentException if the {@code anchor} is null
      */
     public AlgorithmChecker(TrustAnchor anchor,
-            AlgorithmConstraints constraints,
-            Date pkixdate) {
+            AlgorithmConstraints constraints, Date pkixdate, String variant) {
 
         if (anchor != null) {
             if (anchor.getTrustedCert() != null) {
@@ -207,6 +183,7 @@
         this.constraints = constraints;
         this.pkixdate = pkixdate;
         this.jarTimestamp = null;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
     }
 
     /**
@@ -217,11 +194,13 @@
      *     certificate
      * @param pkixdate Date the constraints are checked against. The value is
      *             either the PKIXParameter date or null for the current date.
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      *
      * @throws IllegalArgumentException if the {@code anchor} is null
      */
-    public AlgorithmChecker(TrustAnchor anchor, Date pkixdate) {
-        this(anchor, certPathDefaultConstraints, pkixdate);
+    public AlgorithmChecker(TrustAnchor anchor, Date pkixdate, String variant) {
+        this(anchor, certPathDefaultConstraints, pkixdate, variant);
     }
 
     // Check this 'cert' for restrictions in the AnchorCertificates
@@ -286,6 +265,28 @@
                 null, null, -1, PKIXReason.INVALID_KEY_USAGE);
         }
 
+        X509CertImpl x509Cert;
+        AlgorithmId algorithmId;
+        try {
+            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
+            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
+        } catch (CertificateException ce) {
+            throw new CertPathValidatorException(ce);
+        }
+
+        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
+        PublicKey currPubKey = cert.getPublicKey();
+        String currSigAlg = x509Cert.getSigAlgName();
+
+        // Check the signature algorithm and parameters against constraints.
+        if (!constraints.permits(SIGNATURE_PRIMITIVE_SET, currSigAlg,
+                currSigAlgParams)) {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on signature " +
+                            "algorithm: " + currSigAlg, null, null, -1,
+                    BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
         // Assume all key usage bits are set if key usage is not present
         Set<CryptoPrimitive> primitives = KU_PRIMITIVE_SET;
 
@@ -322,101 +323,74 @@
             }
         }
 
-        PublicKey currPubKey = cert.getPublicKey();
+        ConstraintsParameters cp =
+                new ConstraintsParameters((X509Certificate)cert,
+                        trustedMatch, pkixdate, jarTimestamp, variant);
 
+        // Check against local constraints if it is DisabledAlgorithmConstraints
         if (constraints instanceof DisabledAlgorithmConstraints) {
-            // Check against DisabledAlgorithmConstraints certpath constraints.
-            // permits() will throw exception on failure.
-            ((DisabledAlgorithmConstraints)constraints).permits(primitives,
-                new CertConstraintParameters((X509Certificate)cert,
-                        trustedMatch, pkixdate, jarTimestamp));
-            // If there is no previous key, set one and exit
-            if (prevPubKey == null) {
-                prevPubKey = currPubKey;
-                return;
-            }
-        }
+            ((DisabledAlgorithmConstraints)constraints).permits(currSigAlg, cp);
+            // DisabledAlgorithmsConstraints does not check primitives, so key
+            // additional key check.
 
-        X509CertImpl x509Cert;
-        AlgorithmId algorithmId;
-        try {
-            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
-            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
-        } catch (CertificateException ce) {
-            throw new CertPathValidatorException(ce);
-        }
-
-        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
-        String currSigAlg = x509Cert.getSigAlgName();
-
-        // If 'constraints' is not of DisabledAlgorithmConstraints, check all
-        // everything individually
-        if (!(constraints instanceof DisabledAlgorithmConstraints)) {
-            // Check the current signature algorithm
-            if (!constraints.permits(
-                    SIGNATURE_PRIMITIVE_SET,
-                    currSigAlg, currSigAlgParams)) {
-                throw new CertPathValidatorException(
-                        "Algorithm constraints check failed on signature " +
-                                "algorithm: " + currSigAlg, null, null, -1,
-                        BasicReason.ALGORITHM_CONSTRAINED);
-            }
-
+        } else {
+            // Perform the default constraints checking anyway.
+            certPathDefaultConstraints.permits(currSigAlg, cp);
+            // Call locally set constraints to check key with primitives.
             if (!constraints.permits(primitives, currPubKey)) {
                 throw new CertPathValidatorException(
-                        "Algorithm constraints check failed on keysize: " +
-                                sun.security.util.KeyUtil.getKeySize(currPubKey),
+                        "Algorithm constraints check failed on key " +
+                                currPubKey.getAlgorithm() + " with size of " +
+                                sun.security.util.KeyUtil.getKeySize(currPubKey) +
+                                "bits",
                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
         }
 
+        // If there is no previous key, set one and exit
+        if (prevPubKey == null) {
+            prevPubKey = currPubKey;
+            return;
+        }
+
         // Check with previous cert for signature algorithm and public key
-        if (prevPubKey != null) {
-            if (!constraints.permits(
-                    SIGNATURE_PRIMITIVE_SET,
-                    currSigAlg, prevPubKey, currSigAlgParams)) {
-                throw new CertPathValidatorException(
+        if (!constraints.permits(
+                SIGNATURE_PRIMITIVE_SET,
+                currSigAlg, prevPubKey, currSigAlgParams)) {
+            throw new CertPathValidatorException(
                     "Algorithm constraints check failed on " +
                             "signature algorithm: " + currSigAlg,
                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
+        // Inherit key parameters from previous key
+        if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
+            // Inherit DSA parameters from previous key
+            if (!(prevPubKey instanceof DSAPublicKey)) {
+                throw new CertPathValidatorException("Input key is not " +
+                        "of a appropriate type for inheriting parameters");
             }
 
-            // Inherit key parameters from previous key
-            if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
-                // Inherit DSA parameters from previous key
-                if (!(prevPubKey instanceof DSAPublicKey)) {
-                    throw new CertPathValidatorException("Input key is not " +
-                        "of a appropriate type for inheriting parameters");
-                }
+            DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
+            if (params == null) {
+                throw new CertPathValidatorException(
+                        "Key parameters missing from public key.");
+            }
 
-                DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
-                if (params == null) {
-                    throw new CertPathValidatorException(
-                        "Key parameters missing from public key.");
-                }
-
-                try {
-                    BigInteger y = ((DSAPublicKey)currPubKey).getY();
-                    KeyFactory kf = KeyFactory.getInstance("DSA");
-                    DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
-                                                       params.getP(),
-                                                       params.getQ(),
-                                                       params.getG());
-                    currPubKey = kf.generatePublic(ks);
-                } catch (GeneralSecurityException e) {
-                    throw new CertPathValidatorException("Unable to generate " +
+            try {
+                BigInteger y = ((DSAPublicKey)currPubKey).getY();
+                KeyFactory kf = KeyFactory.getInstance("DSA");
+                DSAPublicKeySpec ks = new DSAPublicKeySpec(y, params.getP(),
+                        params.getQ(), params.getG());
+                currPubKey = kf.generatePublic(ks);
+            } catch (GeneralSecurityException e) {
+                throw new CertPathValidatorException("Unable to generate " +
                         "key with inherited parameters: " + e.getMessage(), e);
-                }
             }
         }
 
         // reset the previous public key
         prevPubKey = currPubKey;
-
-        // check the extended key usage, ignore the check now
-        // List<String> extendedKeyUsages = x509Cert.getExtendedKeyUsage();
-
-        // DO NOT remove any unresolved critical extensions
     }
 
     /**
@@ -456,8 +430,10 @@
      *
      * @param key the public key to verify the CRL signature
      * @param crl the target CRL
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    static void check(PublicKey key, X509CRL crl)
+    static void check(PublicKey key, X509CRL crl, String variant)
                         throws CertPathValidatorException {
 
         X509CRLImpl x509CRLImpl = null;
@@ -468,7 +444,7 @@
         }
 
         AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
-        check(key, algorithmId);
+        check(key, algorithmId, variant);
     }
 
     /**
@@ -476,20 +452,16 @@
      *
      * @param key the public key to verify the CRL signature
      * @param algorithmId signature algorithm Algorithm ID
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    static void check(PublicKey key, AlgorithmId algorithmId)
+    static void check(PublicKey key, AlgorithmId algorithmId, String variant)
                         throws CertPathValidatorException {
         String sigAlgName = algorithmId.getName();
         AlgorithmParameters sigAlgParams = algorithmId.getParameters();
 
-        if (!certPathDefaultConstraints.permits(
-                SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
-            throw new CertPathValidatorException(
-                "Algorithm constraints check failed on signature algorithm: " +
-                sigAlgName + " is disabled",
-                null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
+        certPathDefaultConstraints.permits(new ConstraintsParameters(
+                sigAlgName, sigAlgParams, key, variant));
     }
-
 }
 
--- a/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 import java.util.*;
 
 import sun.security.util.Debug;
+import sun.security.validator.Validator;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.x509.*;
 
@@ -66,6 +67,20 @@
      * an X509CRLSelector with certificateChecking set.
      */
     public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
+            boolean signFlag, PublicKey prevKey, String provider,
+            List<CertStore> certStores, boolean[] reasonsMask,
+            Set<TrustAnchor> trustAnchors, Date validity, String variant)
+            throws CertStoreException
+    {
+        return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
+                reasonsMask, trustAnchors, validity, variant);
+    }
+    /**
+     * Return the X509CRLs matching this selector. The selector must be
+     * an X509CRLSelector with certificateChecking set.
+     */
+    // Called by com.sun.deploy.security.RevocationChecker
+    public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
                                               boolean signFlag,
                                               PublicKey prevKey,
                                               String provider,
@@ -76,7 +91,7 @@
         throws CertStoreException
     {
         return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
-                       reasonsMask, trustAnchors, validity);
+                reasonsMask, trustAnchors, validity, Validator.VAR_GENERIC);
     }
 
     /**
@@ -91,7 +106,8 @@
                                               List<CertStore> certStores,
                                               boolean[] reasonsMask,
                                               Set<TrustAnchor> trustAnchors,
-                                              Date validity)
+                                              Date validity,
+                                              String variant)
         throws CertStoreException
     {
         X509Certificate cert = selector.getCertificateChecking();
@@ -120,7 +136,7 @@
                 DistributionPoint point = t.next();
                 Collection<X509CRL> crls = getCRLs(selector, certImpl,
                     point, reasonsMask, signFlag, prevKey, prevCert, provider,
-                    certStores, trustAnchors, validity);
+                    certStores, trustAnchors, validity, variant);
                 results.addAll(crls);
             }
             if (debug != null) {
@@ -145,7 +161,7 @@
         X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask,
         boolean signFlag, PublicKey prevKey, X509Certificate prevCert,
         String provider, List<CertStore> certStores,
-        Set<TrustAnchor> trustAnchors, Date validity)
+        Set<TrustAnchor> trustAnchors, Date validity, String variant)
             throws CertStoreException {
 
         // check for full name
@@ -208,7 +224,7 @@
                 selector.setIssuerNames(null);
                 if (selector.match(crl) && verifyCRL(certImpl, point, crl,
                         reasonsMask, signFlag, prevKey, prevCert, provider,
-                        trustAnchors, certStores, validity)) {
+                        trustAnchors, certStores, validity, variant)) {
                     crls.add(crl);
                 }
             } catch (IOException | CRLException e) {
@@ -316,7 +332,7 @@
         X509CRL crl, boolean[] reasonsMask, boolean signFlag,
         PublicKey prevKey, X509Certificate prevCert, String provider,
         Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
-        Date validity) throws CRLException, IOException {
+        Date validity, String variant) throws CRLException, IOException {
 
         if (debug != null) {
             debug.println("DistributionPointFetcher.verifyCRL: " +
@@ -663,7 +679,7 @@
 
         // check the crl signature algorithm
         try {
-            AlgorithmChecker.check(prevKey, crl);
+            AlgorithmChecker.check(prevKey, crl, variant);
         } catch (CertPathValidatorException cpve) {
             if (debug != null) {
                 debug.println("CRL signature algorithm check failed: " + cpve);
--- a/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
 
 import sun.security.action.GetIntegerAction;
 import sun.security.util.Debug;
+import sun.security.validator.Validator;
 import sun.security.x509.AccessDescription;
 import sun.security.x509.AuthorityInfoAccessExtension;
 import sun.security.x509.GeneralName;
@@ -94,42 +95,6 @@
 
     private OCSP() {}
 
-    /**
-     * Obtains the revocation status of a certificate using OCSP using the most
-     * common defaults. The OCSP responder URI is retrieved from the
-     * certificate's AIA extension. The OCSP responder certificate is assumed
-     * to be the issuer's certificate (or issued by the issuer CA).
-     *
-     * @param cert the certificate to be checked
-     * @param issuerCert the issuer certificate
-     * @return the RevocationStatus
-     * @throws IOException if there is an exception connecting to or
-     *    communicating with the OCSP responder
-     * @throws CertPathValidatorException if an exception occurs while
-     *    encoding the OCSP Request or validating the OCSP Response
-     */
-    public static RevocationStatus check(X509Certificate cert,
-                                         X509Certificate issuerCert)
-        throws IOException, CertPathValidatorException {
-        CertId certId = null;
-        URI responderURI = null;
-        try {
-            X509CertImpl certImpl = X509CertImpl.toImpl(cert);
-            responderURI = getResponderURI(certImpl);
-            if (responderURI == null) {
-                throw new CertPathValidatorException
-                    ("No OCSP Responder URI in certificate");
-            }
-            certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
-        } catch (CertificateException | IOException e) {
-            throw new CertPathValidatorException
-                ("Exception while encoding OCSPRequest", e);
-        }
-        OCSPResponse ocspResponse = check(Collections.singletonList(certId),
-            responderURI, new OCSPResponse.IssuerInfo(issuerCert), null, null,
-            Collections.<Extension>emptyList());
-        return (RevocationStatus)ocspResponse.getSingleResponse(certId);
-    }
 
     /**
      * Obtains the revocation status of a certificate using OCSP.
@@ -146,6 +111,8 @@
      * @throws CertPathValidatorException if an exception occurs while
      *    encoding the OCSP Request or validating the OCSP Response
      */
+
+    // Called by com.sun.deploy.security.TrustDecider
     public static RevocationStatus check(X509Certificate cert,
                                          X509Certificate issuerCert,
                                          URI responderURI,
@@ -154,27 +121,27 @@
         throws IOException, CertPathValidatorException
     {
         return check(cert, issuerCert, responderURI, responderCert, date,
-                     Collections.<Extension>emptyList());
+                     Collections.<Extension>emptyList(), Validator.VAR_GENERIC);
     }
 
-    // Called by com.sun.deploy.security.TrustDecider
+
     public static RevocationStatus check(X509Certificate cert,
-                                         X509Certificate issuerCert,
-                                         URI responderURI,
-                                         X509Certificate responderCert,
-                                         Date date, List<Extension> extensions)
+            X509Certificate issuerCert, URI responderURI,
+            X509Certificate responderCert, Date date, List<Extension> extensions,
+            String variant)
         throws IOException, CertPathValidatorException
     {
-        return check(cert, responderURI, null, issuerCert, responderCert, date, extensions);
+        return check(cert, responderURI, null, issuerCert, responderCert, date,
+                extensions, variant);
     }
 
     public static RevocationStatus check(X509Certificate cert,
             URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
             X509Certificate responderCert, Date date,
-            List<Extension> extensions)
+            List<Extension> extensions, String variant)
             throws IOException, CertPathValidatorException
     {
-        CertId certId = null;
+        CertId certId;
         try {
             X509CertImpl certImpl = X509CertImpl.toImpl(cert);
             certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
@@ -184,7 +151,7 @@
         }
         OCSPResponse ocspResponse = check(Collections.singletonList(certId),
                 responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
-                responderCert, date, extensions);
+                responderCert, date, extensions, variant);
         return (RevocationStatus) ocspResponse.getSingleResponse(certId);
     }
 
@@ -206,10 +173,10 @@
      * @throws CertPathValidatorException if an exception occurs while
      *    encoding the OCSP Request or validating the OCSP Response
      */
-        static OCSPResponse check(List<CertId> certIds, URI responderURI,
+    static OCSPResponse check(List<CertId> certIds, URI responderURI,
                               OCSPResponse.IssuerInfo issuerInfo,
                               X509Certificate responderCert, Date date,
-                              List<Extension> extensions)
+                              List<Extension> extensions, String variant)
         throws IOException, CertPathValidatorException
     {
         byte[] nonce = null;
@@ -226,7 +193,7 @@
 
             // verify the response
             ocspResponse.verify(certIds, issuerInfo, responderCert, date,
-                    nonce);
+                    nonce, variant);
         } catch (IOException ioe) {
             throw new CertPathValidatorException(
                 "Unable to determine revocation status due to network error",
--- a/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 import javax.security.auth.x500.X500Principal;
 
@@ -375,7 +374,8 @@
     }
 
     void verify(List<CertId> certIds, IssuerInfo issuerInfo,
-            X509Certificate responderCert, Date date, byte[] nonce)
+            X509Certificate responderCert, Date date, byte[] nonce,
+            String variant)
         throws CertPathValidatorException
     {
         switch (responseStatus) {
@@ -508,7 +508,8 @@
                 // Check algorithm constraints specified in security property
                 // "jdk.certpath.disabledAlgorithms".
                 AlgorithmChecker algChecker =
-                        new AlgorithmChecker(issuerInfo.getAnchor(), date);
+                        new AlgorithmChecker(issuerInfo.getAnchor(), date,
+                                variant);
                 algChecker.init(false);
                 algChecker.check(signerCert, Collections.<String>emptySet());
 
@@ -568,7 +569,7 @@
         if (signerCert != null) {
             // Check algorithm constraints specified in security property
             // "jdk.certpath.disabledAlgorithms".
-            AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId);
+            AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId, variant);
 
             if (!verifySignature(signerCert)) {
                 throw new CertPathValidatorException(
--- a/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -87,6 +87,7 @@
         private Set<TrustAnchor> anchors;
         private List<X509Certificate> certs;
         private Timestamp timestamp;
+        private String variant;
 
         ValidatorParams(CertPath cp, PKIXParameters params)
             throws InvalidAlgorithmParameterException
@@ -102,8 +103,9 @@
         ValidatorParams(PKIXParameters params)
             throws InvalidAlgorithmParameterException
         {
-            if (params instanceof PKIXTimestampParameters) {
-                timestamp = ((PKIXTimestampParameters) params).getTimestamp();
+            if (params instanceof PKIXExtendedParameters) {
+                timestamp = ((PKIXExtendedParameters) params).getTimestamp();
+                variant = ((PKIXExtendedParameters) params).getVariant();
             }
 
             this.anchors = params.getTrustAnchors();
@@ -199,6 +201,10 @@
         Timestamp timestamp() {
             return timestamp;
         }
+
+        String variant() {
+            return variant;
+        }
     }
 
     static class BuilderParams extends ValidatorParams {
--- a/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -173,9 +173,10 @@
         // add standard checkers that we will be using
         certPathCheckers.add(untrustedChecker);
         if (params.timestamp() == null) {
-            certPathCheckers.add(new AlgorithmChecker(anchor, params.date()));
+            certPathCheckers.add(new AlgorithmChecker(anchor, params.date(), null));
         } else {
-            certPathCheckers.add(new AlgorithmChecker(params.timestamp()));
+            certPathCheckers.add(new AlgorithmChecker(null,
+                    params.timestamp(), params.variant()));
         }
         certPathCheckers.add(new KeyChecker(certPathLen,
                                             params.targetCertConstraints()));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/PKIXExtendedParameters.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package sun.security.provider.certpath;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Timestamp;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStore;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.TrustAnchor;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is a wrapper for PKIXBuilderParameters so that a Timestamp object
+ * and a string for the variant type, can be passed when doing certpath
+ * checking.
+ */
+
+public class PKIXExtendedParameters extends PKIXBuilderParameters {
+
+    private final PKIXBuilderParameters p;
+    private Timestamp jarTimestamp;
+    private final String variant;
+
+    public PKIXExtendedParameters(PKIXBuilderParameters params,
+            Timestamp timestamp, String variant)
+            throws InvalidAlgorithmParameterException {
+        super(params.getTrustAnchors(), null);
+        p = params;
+        jarTimestamp = timestamp;
+        this.variant = variant;
+    }
+
+    public Timestamp getTimestamp() {
+        return jarTimestamp;
+    }
+    public void setTimestamp(Timestamp t) {
+        jarTimestamp = t;
+    }
+
+    public String getVariant() {
+        return variant;
+    }
+
+    @Override
+    public void setDate(Date d) {
+        p.setDate(d);
+    }
+
+    @Override
+    public void addCertPathChecker(PKIXCertPathChecker c) {
+        p.addCertPathChecker(c);
+    }
+
+    @Override
+    public void setMaxPathLength(int maxPathLength) {
+        p.setMaxPathLength(maxPathLength);
+    }
+
+    @Override
+    public int getMaxPathLength() {
+        return p.getMaxPathLength();
+    }
+
+    @Override
+    public String toString() {
+        return p.toString();
+    }
+
+    @Override
+    public Set<TrustAnchor> getTrustAnchors() {
+        return p.getTrustAnchors();
+    }
+
+    @Override
+    public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
+            throws InvalidAlgorithmParameterException {
+        // To avoid problems with PKIXBuilderParameter's constructors
+        if (p == null) {
+            return;
+        }
+        p.setTrustAnchors(trustAnchors);
+    }
+
+    @Override
+    public Set<String> getInitialPolicies() {
+        return p.getInitialPolicies();
+    }
+
+    @Override
+    public void setInitialPolicies(Set<String> initialPolicies) {
+        p.setInitialPolicies(initialPolicies);
+    }
+
+    @Override
+    public void setCertStores(List<CertStore> stores) {
+        p.setCertStores(stores);
+    }
+
+    @Override
+    public void addCertStore(CertStore store) {
+        p.addCertStore(store);
+    }
+
+    @Override
+    public List<CertStore> getCertStores() {
+        return p.getCertStores();
+    }
+
+    @Override
+    public void setRevocationEnabled(boolean val) {
+        p.setRevocationEnabled(val);
+    }
+
+    @Override
+    public boolean isRevocationEnabled() {
+        return p.isRevocationEnabled();
+    }
+
+    @Override
+    public void setExplicitPolicyRequired(boolean val) {
+        p.setExplicitPolicyRequired(val);
+    }
+
+    @Override
+    public boolean isExplicitPolicyRequired() {
+        return p.isExplicitPolicyRequired();
+    }
+
+    @Override
+    public void setPolicyMappingInhibited(boolean val) {
+        p.setPolicyMappingInhibited(val);
+    }
+
+    @Override
+    public boolean isPolicyMappingInhibited() {
+        return p.isPolicyMappingInhibited();
+    }
+
+    @Override
+    public void setAnyPolicyInhibited(boolean val) {
+        p.setAnyPolicyInhibited(val);
+    }
+
+    @Override
+    public boolean isAnyPolicyInhibited() {
+        return p.isAnyPolicyInhibited();
+    }
+
+    @Override
+    public void setPolicyQualifiersRejected(boolean qualifiersRejected) {
+        p.setPolicyQualifiersRejected(qualifiersRejected);
+    }
+
+    @Override
+    public boolean getPolicyQualifiersRejected() {
+        return p.getPolicyQualifiersRejected();
+    }
+
+    @Override
+    public Date getDate() {
+        return p.getDate();
+    }
+
+    @Override
+    public void setCertPathCheckers(List<PKIXCertPathChecker> checkers) {
+        p.setCertPathCheckers(checkers);
+    }
+
+    @Override
+    public List<PKIXCertPathChecker> getCertPathCheckers() {
+        return p.getCertPathCheckers();
+    }
+
+    @Override
+    public String getSigProvider() {
+        return p.getSigProvider();
+    }
+
+    @Override
+    public void setSigProvider(String sigProvider) {
+        p.setSigProvider(sigProvider);
+    }
+
+    @Override
+    public CertSelector getTargetCertConstraints() {
+        return p.getTargetCertConstraints();
+    }
+
+    @Override
+    public void setTargetCertConstraints(CertSelector selector) {
+        // To avoid problems with PKIXBuilderParameter's constructors
+        if (p == null) {
+            return;
+        }
+        p.setTargetCertConstraints(selector);
+    }
+
+}
--- a/src/java.base/share/classes/sun/security/provider/certpath/PKIXTimestampParameters.java	Thu Feb 09 17:21:47 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.provider.certpath;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.Timestamp;
-import java.security.cert.CertSelector;
-import java.security.cert.CertStore;
-import java.security.cert.PKIXBuilderParameters;
-import java.security.cert.PKIXCertPathChecker;
-import java.security.cert.TrustAnchor;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
-/**
- * This class is a wrapper for PKIXBuilderParameters so that a Timestamp object
- * can be passed alone when PKIXCertPath is checking signed jar files.
- */
-
-public class PKIXTimestampParameters extends PKIXBuilderParameters {
-
-    private final PKIXBuilderParameters p;
-    private Timestamp jarTimestamp;
-
-    public PKIXTimestampParameters(PKIXBuilderParameters params,
-            Timestamp timestamp) throws InvalidAlgorithmParameterException {
-        super(params.getTrustAnchors(), null);
-        p = params;
-        jarTimestamp = timestamp;
-    }
-
-    public Timestamp getTimestamp() {
-        return jarTimestamp;
-    }
-    public void setTimestamp(Timestamp t) {
-        jarTimestamp = t;
-    }
-
-    @Override
-    public void setDate(Date d) {
-        p.setDate(d);
-    }
-
-    @Override
-    public void addCertPathChecker(PKIXCertPathChecker c) {
-        p.addCertPathChecker(c);
-    }
-
-    @Override
-    public void setMaxPathLength(int maxPathLength) {
-        p.setMaxPathLength(maxPathLength);
-    }
-
-    @Override
-    public int getMaxPathLength() {
-        return p.getMaxPathLength();
-    }
-
-    @Override
-    public String toString() {
-        return p.toString();
-    }
-
-    @Override
-    public Set<TrustAnchor> getTrustAnchors() {
-        return p.getTrustAnchors();
-    }
-
-    @Override
-    public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
-            throws InvalidAlgorithmParameterException {
-        // To avoid problems with PKIXBuilderParameter's constructors
-        if (p == null) {
-            return;
-        }
-        p.setTrustAnchors(trustAnchors);
-    }
-
-    @Override
-    public Set<String> getInitialPolicies() {
-        return p.getInitialPolicies();
-    }
-
-    @Override
-    public void setInitialPolicies(Set<String> initialPolicies) {
-        p.setInitialPolicies(initialPolicies);
-    }
-
-    @Override
-    public void setCertStores(List<CertStore> stores) {
-        p.setCertStores(stores);
-    }
-
-    @Override
-    public void addCertStore(CertStore store) {
-        p.addCertStore(store);
-    }
-
-    @Override
-    public List<CertStore> getCertStores() {
-        return p.getCertStores();
-    }
-
-    @Override
-    public void setRevocationEnabled(boolean val) {
-        p.setRevocationEnabled(val);
-    }
-
-    @Override
-    public boolean isRevocationEnabled() {
-        return p.isRevocationEnabled();
-    }
-
-    @Override
-    public void setExplicitPolicyRequired(boolean val) {
-        p.setExplicitPolicyRequired(val);
-    }
-
-    @Override
-    public boolean isExplicitPolicyRequired() {
-        return p.isExplicitPolicyRequired();
-    }
-
-    @Override
-    public void setPolicyMappingInhibited(boolean val) {
-        p.setPolicyMappingInhibited(val);
-    }
-
-    @Override
-    public boolean isPolicyMappingInhibited() {
-        return p.isPolicyMappingInhibited();
-    }
-
-    @Override
-    public void setAnyPolicyInhibited(boolean val) {
-        p.setAnyPolicyInhibited(val);
-    }
-
-    @Override
-    public boolean isAnyPolicyInhibited() {
-        return p.isAnyPolicyInhibited();
-    }
-
-    @Override
-    public void setPolicyQualifiersRejected(boolean qualifiersRejected) {
-        p.setPolicyQualifiersRejected(qualifiersRejected);
-    }
-
-    @Override
-    public boolean getPolicyQualifiersRejected() {
-        return p.getPolicyQualifiersRejected();
-    }
-
-    @Override
-    public Date getDate() {
-        return p.getDate();
-    }
-
-    @Override
-    public void setCertPathCheckers(List<PKIXCertPathChecker> checkers) {
-        p.setCertPathCheckers(checkers);
-    }
-
-    @Override
-    public List<PKIXCertPathChecker> getCertPathCheckers() {
-        return p.getCertPathCheckers();
-    }
-
-    @Override
-    public String getSigProvider() {
-        return p.getSigProvider();
-    }
-
-    @Override
-    public void setSigProvider(String sigProvider) {
-        p.setSigProvider(sigProvider);
-    }
-
-    @Override
-    public CertSelector getTargetCertConstraints() {
-        return p.getTargetCertConstraints();
-    }
-
-    @Override
-    public void setTargetCertConstraints(CertSelector selector) {
-        // To avoid problems with PKIXBuilderParameter's constructors
-        if (p == null) {
-            return;
-        }
-        p.setTargetCertConstraints(selector);
-    }
-
-}
--- a/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -579,7 +579,7 @@
                     approvedCRLs.addAll(DistributionPointFetcher.getCRLs(
                                         sel, signFlag, prevKey, prevCert,
                                         params.sigProvider(), certStores,
-                                        reasonsMask, anchors, null));
+                                        reasonsMask, anchors, null, params.variant()));
                 }
             } catch (CertStoreException e) {
                 if (e instanceof CertStoreTypeException) {
@@ -727,7 +727,7 @@
                     }
                 }
                 response.verify(Collections.singletonList(certId), issuerInfo,
-                        responderCert, params.date(), nonce);
+                        responderCert, params.date(), nonce, params.variant());
 
             } else {
                 URI responderURI = (this.responderURI != null)
@@ -741,7 +741,7 @@
 
                 response = OCSP.check(Collections.singletonList(certId),
                         responderURI, issuerInfo, responderCert, null,
-                        ocspExtensions);
+                        ocspExtensions, params.variant());
             }
         } catch (IOException e) {
             throw new CertPathValidatorException(
@@ -853,7 +853,7 @@
                     if (DistributionPointFetcher.verifyCRL(
                             certImpl, point, crl, reasonsMask, signFlag,
                             prevKey, null, params.sigProvider(), anchors,
-                            certStores, params.date()))
+                            certStores, params.date(), params.variant()))
                     {
                         results.add(crl);
                     }
--- a/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -344,7 +344,7 @@
 
                 // add the algorithm checker
                 checkers.add(new AlgorithmChecker(builder.trustAnchor,
-                        buildParams.date()));
+                        buildParams.date(), null));
 
                 BasicChecker basicChecker = null;
                 if (nextState.keyParamsNeeded()) {
--- a/src/java.base/share/classes/sun/security/ssl/EllipticCurvesExtension.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/EllipticCurvesExtension.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,9 @@
 
 final class EllipticCurvesExtension extends HelloExtension {
 
+    /* Class and subclass dynamic debugging support */
+    private static final Debug debug = Debug.getInstance("ssl");
+
     private static final int ARBITRARY_PRIME = 0xff01;
     private static final int ARBITRARY_CHAR2 = 0xff02;
 
@@ -159,6 +162,11 @@
                     }   // ignore unknown curves
                 }
             }
+            if (idList.isEmpty() && JsseJce.isEcAvailable()) {
+                throw new IllegalArgumentException(
+                    "System property jdk.tls.namedGroups(" + property + ") " +
+                    "contains no supported elliptic curves");
+            }
         } else {        // default curves
             int[] ids;
             if (requireFips) {
@@ -183,16 +191,17 @@
             }
         }
 
-        if (idList.isEmpty()) {
-            throw new IllegalArgumentException(
-                "System property jdk.tls.namedGroups(" + property + ") " +
-                "contains no supported elliptic curves");
-        } else {
-            supportedCurveIds = new int[idList.size()];
-            int i = 0;
-            for (Integer id : idList) {
-                supportedCurveIds[i++] = id;
-            }
+        if (debug != null && idList.isEmpty()) {
+            Debug.log(
+                "Initialized [jdk.tls.namedGroups|default] list contains " +
+                "no available elliptic curves. " +
+                (property != null ? "(" + property + ")" : "[Default]"));
+        }
+
+        supportedCurveIds = new int[idList.size()];
+        int i = 0;
+        for (Integer id : idList) {
+            supportedCurveIds[i++] = id;
         }
     }
 
--- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 
 import sun.security.provider.certpath.AlgorithmChecker;
 import sun.security.action.GetPropertyAction;
+import sun.security.validator.Validator;
 
 public abstract class SSLContextImpl extends SSLContextSpi {
 
@@ -1436,7 +1437,7 @@
                 constraints = new SSLAlgorithmConstraints(sslSocket, true);
             }
 
-            checkAlgorithmConstraints(chain, constraints);
+            checkAlgorithmConstraints(chain, constraints, isClient);
         }
     }
 
@@ -1478,12 +1479,12 @@
                 constraints = new SSLAlgorithmConstraints(engine, true);
             }
 
-            checkAlgorithmConstraints(chain, constraints);
+            checkAlgorithmConstraints(chain, constraints, isClient);
         }
     }
 
     private void checkAlgorithmConstraints(X509Certificate[] chain,
-            AlgorithmConstraints constraints) throws CertificateException {
+            AlgorithmConstraints constraints, boolean isClient) throws CertificateException {
 
         try {
             // Does the certificate chain end with a trusted certificate?
@@ -1501,7 +1502,9 @@
 
             // A forward checker, need to check from trust to target
             if (checkedLength >= 0) {
-                AlgorithmChecker checker = new AlgorithmChecker(constraints);
+                AlgorithmChecker checker =
+                        new AlgorithmChecker(constraints, null,
+                                (isClient ? Validator.VAR_TLS_CLIENT : Validator.VAR_TLS_SERVER));
                 checker.init(false);
                 for (int i = checkedLength; i >= 0; i--) {
                     Certificate cert = chain[i];
--- a/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java	Thu Feb 09 18:10:19 2017 +0000
@@ -39,6 +39,7 @@
 import javax.net.ssl.*;
 
 import sun.security.provider.certpath.AlgorithmChecker;
+import sun.security.validator.Validator;
 
 /**
  * The new X509 key manager implementation. The main differences to the
@@ -661,6 +662,15 @@
 
             return CheckResult.OK;
         }
+
+        public String getValidator() {
+            if (this == CLIENT) {
+                return Validator.VAR_TLS_CLIENT;
+            } else if (this == SERVER) {
+                return Validator.VAR_TLS_SERVER;
+            }
+            return Validator.VAR_GENERIC;
+        }
     }
 
     // enum for the result of the extension check
@@ -774,7 +784,8 @@
 
             // check the algorithm constraints
             if (constraints != null &&
-                    !conformsToAlgorithmConstraints(constraints, chain)) {
+                    !conformsToAlgorithmConstraints(constraints, chain,
+                            checkType.getValidator())) {
 
                 if (useDebug) {
                     debug.println("Ignoring alias " + alias +
@@ -811,9 +822,10 @@
     }
 
     private static boolean conformsToAlgorithmConstraints(
-            AlgorithmConstraints constraints, Certificate[] chain) {
+            AlgorithmConstraints constraints, Certificate[] chain,
+            String variant) {
 
-        AlgorithmChecker checker = new AlgorithmChecker(constraints);
+        AlgorithmChecker checker = new AlgorithmChecker(constraints, null, variant);
         try {
             checker.init(false);
         } catch (CertPathValidatorException cpve) {
--- a/src/java.base/share/classes/sun/security/util/CertConstraintParameters.java	Thu Feb 09 17:21:47 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.util;
-
-import java.security.Timestamp;
-import java.security.cert.X509Certificate;
-import java.util.Date;
-
-/**
- * This class is a wrapper for keeping state and passing objects between PKIX,
- * AlgorithmChecker, and DisabledAlgorithmConstraints.
- */
-public class CertConstraintParameters {
-    // A certificate being passed to check against constraints.
-    private final X509Certificate cert;
-    // This is true if the trust anchor in the certificate chain matches a cert
-    // in AnchorCertificates
-    private final boolean trustedMatch;
-    // PKIXParameter date
-    private final Date pkixDate;
-    // Timestamp of the signed JAR file
-    private final Timestamp jarTimestamp;
-
-    public CertConstraintParameters(X509Certificate c, boolean match,
-            Date pkixdate, Timestamp jarTime) {
-        cert = c;
-        trustedMatch = match;
-        pkixDate = pkixdate;
-        jarTimestamp = jarTime;
-    }
-
-    public CertConstraintParameters(X509Certificate c) {
-        this(c, false, null, null);
-    }
-
-    // Returns if the trust anchor has a match if anchor checking is enabled.
-    public boolean isTrustedMatch() {
-        return trustedMatch;
-    }
-
-    public X509Certificate getCertificate() {
-        return cert;
-    }
-
-    public Date getPKIXParamDate() {
-        return pkixDate;
-    }
-
-    public Timestamp getJARTimestamp() {
-        return jarTimestamp;
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016, 2017 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import sun.security.validator.Validator;
+
+import java.security.AlgorithmParameters;
+import java.security.Key;
+import java.security.Timestamp;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+/**
+ * This class contains parameters for checking against constraints that extend
+ * past the publicly available parameters in java.security.AlgorithmConstraints.
+
+ * This is currently on passed between  between PKIX, AlgorithmChecker,
+ * and DisabledAlgorithmConstraints.
+ */
+public class ConstraintsParameters {
+    /*
+     * The below 3 values are used the same as the permit() methods
+     * published in java.security.AlgorithmConstraints.
+     */
+    // Algorithm string to be checked against constraints
+    private final String algorithm;
+    // AlgorithmParameters to the algorithm being checked
+    private final AlgorithmParameters algParams;
+    // Public Key being checked against constraints
+    private final Key publicKey;
+
+    /*
+     * New values that are checked against constraints that the current public
+     * API does not support.
+     */
+    // A certificate being passed to check against constraints.
+    private final X509Certificate cert;
+    // This is true if the trust anchor in the certificate chain matches a cert
+    // in AnchorCertificates
+    private final boolean trustedMatch;
+    // PKIXParameter date
+    private final Date pkixDate;
+    // Timestamp of the signed JAR file
+    private final Timestamp jarTimestamp;
+    private final String variant;
+
+    public ConstraintsParameters(X509Certificate c, boolean match,
+            Date pkixdate, Timestamp jarTime, String variant) {
+        cert = c;
+        trustedMatch = match;
+        pkixDate = pkixdate;
+        jarTimestamp = jarTime;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+        algorithm = null;
+        algParams = null;
+        publicKey = null;
+    }
+
+    public ConstraintsParameters(String algorithm, AlgorithmParameters params,
+            Key key, String variant) {
+        this.algorithm = algorithm;
+        algParams = params;
+        this.publicKey = key;
+        cert = null;
+        trustedMatch = false;
+        pkixDate = null;
+        jarTimestamp = null;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+    }
+
+
+    public ConstraintsParameters(X509Certificate c) {
+        this(c, false, null, null,
+                Validator.VAR_GENERIC);
+    }
+
+    public ConstraintsParameters(Timestamp jarTime) {
+        this(null, false, null, jarTime, Validator.VAR_GENERIC);
+    }
+
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    public AlgorithmParameters getAlgParams() {
+        return algParams;
+    }
+
+    public Key getPublicKey() {
+        return publicKey;
+    }
+    // Returns if the trust anchor has a match if anchor checking is enabled.
+    public boolean isTrustedMatch() {
+        return trustedMatch;
+    }
+
+    public X509Certificate getCertificate() {
+        return cert;
+    }
+
+    public Date getPKIXParamDate() {
+        return pkixDate;
+    }
+
+    public Timestamp getJARTimestamp() {
+        return jarTimestamp;
+    }
+
+    public String getVariant() {
+        return variant;
+    }
+}
--- a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
 
 package sun.security.util;
 
+import sun.security.validator.Validator;
+
 import java.security.CryptoPrimitive;
 import java.security.AlgorithmParameters;
 import java.security.Key;
@@ -32,10 +34,12 @@
 import java.security.cert.CertPathValidatorException.BasicReason;
 import java.security.cert.X509Certificate;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -100,12 +104,6 @@
     @Override
     public final boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, AlgorithmParameters parameters) {
-
-        if (primitives == null || primitives.isEmpty()) {
-            throw new IllegalArgumentException(
-                        "No cryptographic primitive specified");
-        }
-
         return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
     }
 
@@ -133,6 +131,18 @@
         return checkConstraints(primitives, algorithm, key, parameters);
     }
 
+    public final void permits(ConstraintsParameters cp)
+            throws CertPathValidatorException {
+        permits(cp.getAlgorithm(), cp);
+    }
+
+    public final void permits(String algorithm, Key key,
+            AlgorithmParameters params, String variant)
+            throws CertPathValidatorException {
+        permits(algorithm, new ConstraintsParameters(algorithm, params, key,
+                (variant == null) ? Validator.VAR_GENERIC : variant));
+    }
+
     /*
      * Check if a x509Certificate object is permitted.  Check if all
      * algorithms are allowed, certificate constraints, and the
@@ -140,18 +150,10 @@
      *
      * Uses new style permit() which throws exceptions.
      */
-    public final void permits(Set<CryptoPrimitive> primitives,
-            CertConstraintParameters cp) throws CertPathValidatorException {
-        checkConstraints(primitives, cp);
-    }
 
-    /*
-     * Check if Certificate object is within the constraints.
-     * Uses new style permit() which throws exceptions.
-     */
-    public final void permits(Set<CryptoPrimitive> primitives,
-            X509Certificate cert) throws CertPathValidatorException {
-        checkConstraints(primitives, new CertConstraintParameters(cert));
+    public final void permits(String algorithm, ConstraintsParameters cp)
+            throws CertPathValidatorException {
+        algorithmConstraints.permits(algorithm, cp);
     }
 
     // Check if a string is contained inside the property
@@ -174,7 +176,7 @@
             throw new IllegalArgumentException("The key cannot be null");
         }
 
-        // check the signature algorithm
+        // check the signature algorithm with parameters
         if (algorithm != null && algorithm.length() != 0) {
             if (!permits(primitives, algorithm, parameters)) {
                 return false;
@@ -190,36 +192,6 @@
         return algorithmConstraints.permits(key);
     }
 
-    /*
-     * Check algorithm constraints with Certificate
-     * Uses new style permit() which throws exceptions.
-     */
-    private void checkConstraints(Set<CryptoPrimitive> primitives,
-            CertConstraintParameters cp) throws CertPathValidatorException {
-
-        X509Certificate cert = cp.getCertificate();
-        String algorithm = cert.getSigAlgName();
-
-        // Check signature algorithm is not disabled
-        if (!permits(primitives, algorithm, null)) {
-            throw new CertPathValidatorException(
-                    "Algorithm constraints check failed on disabled "+
-                            "signature algorithm: " + algorithm,
-                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
-
-        // Check key algorithm is not disabled
-        if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
-            throw new CertPathValidatorException(
-                    "Algorithm constraints check failed on disabled "+
-                            "public key algorithm: " + algorithm,
-                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
-
-        // Check the certificate and key constraints
-        algorithmConstraints.permits(cp);
-
-    }
 
     /**
      * Key and Certificate Constraints
@@ -234,13 +206,13 @@
      * 'true' means the operation is allowed.
      * 'false' means it failed the constraints and is disallowed.
      *
-     * When passing CertConstraintParameters through permit(), an exception
+     * When passing ConstraintsParameters through permit(), an exception
      * will be thrown on a failure to better identify why the operation was
      * disallowed.
      */
 
     private static class Constraints {
-        private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
+        private Map<String, List<Constraint>> constraintsMap = new HashMap<>();
 
         private static class Holder {
             private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
@@ -260,23 +232,22 @@
 
                 // Check if constraint is a complete disabling of an
                 // algorithm or has conditions.
-                String algorithm;
-                String policy;
                 int space = constraintEntry.indexOf(' ');
-                if (space > 0) {
-                    algorithm = AlgorithmDecomposer.hashName(
-                            constraintEntry.substring(0, space).
-                                    toUpperCase(Locale.ENGLISH));
-                    policy = constraintEntry.substring(space + 1);
-                } else {
-                    algorithm = constraintEntry.toUpperCase(Locale.ENGLISH);
-                    if (!constraintsMap.containsKey(algorithm)) {
-                        constraintsMap.putIfAbsent(algorithm,
-                                new HashSet<>());
-                    }
+                String algorithm = AlgorithmDecomposer.hashName(
+                        ((space > 0 ? constraintEntry.substring(0, space) :
+                                constraintEntry).
+                                toUpperCase(Locale.ENGLISH)));
+                List<Constraint> constraintList =
+                        constraintsMap.getOrDefault(algorithm,
+                                new ArrayList<>(1));
+                constraintsMap.putIfAbsent(algorithm, constraintList);
+                if (space <= 0) {
+                    constraintList.add(new DisabledConstraint(algorithm));
                     continue;
                 }
 
+                String policy = constraintEntry.substring(space + 1);
+
                 // Convert constraint conditions into Constraint classes
                 Constraint c, lastConstraint = null;
                 // Allow only one jdkCA entry per constraint entry
@@ -315,7 +286,7 @@
                         c = new jdkCAConstraint(algorithm);
                         jdkCALimit = true;
 
-                    } else if(entry.startsWith("denyAfter") &&
+                    } else if (entry.startsWith("denyAfter") &&
                             (matcher = Holder.DENY_AFTER_PATTERN.matcher(entry))
                                     .matches()) {
                         if (debug != null) {
@@ -332,6 +303,12 @@
                         c = new DenyAfterConstraint(algorithm, year, month,
                                 day);
                         denyAfterLimit = true;
+                    } else if (entry.startsWith("usage")) {
+                        String s[] = (entry.substring(5)).trim().split(" ");
+                        c = new UsageConstraint(algorithm, s);
+                        if (debug != null) {
+                            debug.println("Constraints usage length is " + s.length);
+                        }
                     } else {
                         throw new IllegalArgumentException("Error in security" +
                                 " property. Constraint unknown: " + entry);
@@ -340,11 +317,7 @@
                     // Link multiple conditions for a single constraint
                     // into a linked list.
                     if (lastConstraint == null) {
-                        if (!constraintsMap.containsKey(algorithm)) {
-                            constraintsMap.putIfAbsent(algorithm,
-                                    new HashSet<>());
-                        }
-                        constraintsMap.get(algorithm).add(c);
+                        constraintList.add(c);
                     } else {
                         lastConstraint.nextConstraint = c;
                     }
@@ -354,17 +327,17 @@
         }
 
         // Get applicable constraints based off the signature algorithm
-        private Set<Constraint> getConstraints(String algorithm) {
+        private List<Constraint> getConstraints(String algorithm) {
             return constraintsMap.get(algorithm);
         }
 
         // Check if KeySizeConstraints permit the specified key
         public boolean permits(Key key) {
-            Set<Constraint> set = getConstraints(key.getAlgorithm());
-            if (set == null) {
+            List<Constraint> list = getConstraints(key.getAlgorithm());
+            if (list == null) {
                 return true;
             }
-            for (Constraint constraint : set) {
+            for (Constraint constraint : list) {
                 if (!constraint.permits(key)) {
                     if (debug != null) {
                         debug.println("keySizeConstraint: failed key " +
@@ -377,31 +350,35 @@
         }
 
         // Check if constraints permit this cert.
-        public void permits(CertConstraintParameters cp)
+        public void permits(String algorithm, ConstraintsParameters cp)
                 throws CertPathValidatorException {
             X509Certificate cert = cp.getCertificate();
 
             if (debug != null) {
-                debug.println("Constraints.permits(): " + cert.getSigAlgName());
+                debug.println("Constraints.permits(): " + algorithm +
+                        " Variant: " + cp.getVariant());
             }
 
             // Get all signature algorithms to check for constraints
-            Set<String> algorithms =
-                    AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
-            if (algorithms == null || algorithms.isEmpty()) {
-                return;
+            Set<String> algorithms = new HashSet<>();
+            if (algorithm != null) {
+                algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
             }
 
-            // Attempt to add the public key algorithm to the set
-            algorithms.add(cert.getPublicKey().getAlgorithm());
-
+            // Attempt to add the public key algorithm if cert provided
+            if (cert != null) {
+                algorithms.add(cert.getPublicKey().getAlgorithm());
+            }
+            if (cp.getPublicKey() != null) {
+                algorithms.add(cp.getPublicKey().getAlgorithm());
+            }
             // Check all applicable constraints
-            for (String algorithm : algorithms) {
-                Set<Constraint> set = getConstraints(algorithm);
-                if (set == null) {
+            for (String alg : algorithms) {
+                List<Constraint> list = getConstraints(alg);
+                if (list == null) {
                     continue;
                 }
-                for (Constraint constraint : set) {
+                for (Constraint constraint : list) {
                     constraint.permits(cp);
                 }
             }
@@ -467,17 +444,17 @@
 
         /**
          * Check if an algorithm constraint is permitted with a given
-         * CertConstraintParameters.
+         * ConstraintsParameters.
          *
          * If the check inside of {@code permits()} fails, it must call
-         * {@code next()} with the same {@code CertConstraintParameters}
+         * {@code next()} with the same {@code ConstraintsParameters}
          * parameter passed if multiple constraints need to be checked.
          *
          * @param cp CertConstraintParameter containing certificate info
          * @throws CertPathValidatorException if constraint disallows.
          *
          */
-        public abstract void permits(CertConstraintParameters cp)
+        public abstract void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException;
 
         /**
@@ -491,12 +468,12 @@
          * were disallowed, the last constraint will throw
          * {@code CertPathValidatorException}.
          *
-         * @param cp CertConstraintParameters
+         * @param cp ConstraintsParameters
          * @return 'true' if constraint allows the operation, 'false' if
          * we are at the end of the constraint list or,
          * {@code nextConstraint} is null.
          */
-        boolean next(CertConstraintParameters cp)
+        boolean next(ConstraintsParameters cp)
                 throws CertPathValidatorException {
             if (nextConstraint != null) {
                 nextConstraint.permits(cp);
@@ -525,6 +502,14 @@
             }
             return false;
         }
+
+        String extendedMsg(ConstraintsParameters cp) {
+            return (cp.getCertificate() == null ? "." :
+                    " used with certificate: " +
+                            cp.getCertificate().getSubjectX500Principal() +
+                    (cp.getVariant() != Validator.VAR_GENERIC ?
+                            ".  Usage was " + cp.getVariant() : "."));
+        }
     }
 
     /*
@@ -537,11 +522,11 @@
         }
 
         /*
-         * Check if CertConstraintParameters has a trusted match, if it does
+         * Check if ConstraintsParameters has a trusted match, if it does
          * call next() for any following constraints. If it does not, exit
          * as this constraint(s) does not restrict the operation.
          */
-        public void permits(CertConstraintParameters cp)
+        public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
             if (debug != null) {
                 debug.println("jdkCAConstraints.permits(): " + algorithm);
@@ -554,8 +539,7 @@
                 }
                 throw new CertPathValidatorException(
                         "Algorithm constraints check failed on certificate " +
-                                "anchor limits. " + algorithm + " used with " +
-                                cp.getCertificate().getSubjectX500Principal(),
+                        "anchor limits. " + algorithm + extendedMsg(cp),
                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
         }
@@ -615,7 +599,7 @@
           * constraints. Throw an exception if this is the last constraint.
           */
          @Override
-         public void permits(CertConstraintParameters cp)
+         public void permits(ConstraintsParameters cp)
                  throws CertPathValidatorException {
              Date currentDate;
              String errmsg;
@@ -628,7 +612,7 @@
                  errmsg = "PKIXParameter date: ";
              } else {
                  currentDate = new Date();
-                 errmsg = "Certificate date: ";
+                 errmsg = "Current date: ";
              }
 
              if (!denyAfterDate.after(currentDate)) {
@@ -637,9 +621,9 @@
                  }
                  throw new CertPathValidatorException(
                          "denyAfter constraint check failed: " + algorithm +
-                                 " used with Constraint date: " +
-                                 dateFormat.format(denyAfterDate) + "; "
-                                 + errmsg + dateFormat.format(currentDate),
+                         " used with Constraint date: " +
+                         dateFormat.format(denyAfterDate) + "; " + errmsg +
+                         dateFormat.format(currentDate) + extendedMsg(cp),
                          null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
              }
          }
@@ -661,6 +645,48 @@
      }
 
     /*
+     * The usage constraint is for the "usage" keyword.  It checks against the
+     * variant value in ConstraintsParameters.
+     */
+    private static class UsageConstraint extends Constraint {
+        String[] usages;
+
+        UsageConstraint(String algorithm, String[] usages) {
+            this.algorithm = algorithm;
+            this.usages = usages;
+        }
+
+        public void permits(ConstraintsParameters cp)
+                throws CertPathValidatorException {
+            for (String usage : usages) {
+
+                String v = null;
+                if (usage.compareToIgnoreCase("TLSServer") == 0) {
+                    v = Validator.VAR_TLS_SERVER;
+                } else if (usage.compareToIgnoreCase("TLSClient") == 0) {
+                    v = Validator.VAR_TLS_CLIENT;
+                } else if (usage.compareToIgnoreCase("SignedJAR") == 0) {
+                    v = Validator.VAR_PLUGIN_CODE_SIGNING;
+                }
+
+                if (debug != null) {
+                    debug.println("Checking if usage constraint " + v +
+                            " matches " + cp.getVariant());
+                }
+                if (cp.getVariant().compareTo(v) == 0) {
+                    if (next(cp)) {
+                        return;
+                    }
+                    throw new CertPathValidatorException("Usage constraint " +
+                            usage + " check failed: " + algorithm +
+                            extendedMsg(cp),
+                            null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+                }
+            }
+        }
+    }
+
+    /*
      * This class contains constraints dealing with the key size
      * support limits per algorithm.   e.g.  "keySize <= 1024"
      */
@@ -713,17 +739,22 @@
          * constraint  Any permitted constraint will exit the linked list
          * to allow the operation.
          */
-        public void permits(CertConstraintParameters cp)
+        public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
-            if (!permitsImpl(cp.getCertificate().getPublicKey())) {
+            Key key = null;
+            if (cp.getPublicKey() != null) {
+                key = cp.getPublicKey();
+            } else if (cp.getCertificate() != null) {
+                key = cp.getCertificate().getPublicKey();
+            }
+            if (key != null && !permitsImpl(key)) {
                 if (nextConstraint != null) {
                     nextConstraint.permits(cp);
                     return;
                 }
                 throw new CertPathValidatorException(
                         "Algorithm constraints check failed on keysize limits. "
-                                + algorithm + " " + size + "bit key used with "
-                                + cp.getCertificate().getSubjectX500Principal(),
+                        + algorithm + " " + size + "bit key" + extendedMsg(cp),
                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
         }
@@ -762,5 +793,26 @@
             return true;
         }
     }
+
+    /*
+     * This constraint is used for the complete disabling of the algorithm.
+     */
+    private static class DisabledConstraint extends Constraint {
+        DisabledConstraint(String algo) {
+            algorithm = algo;
+        }
+
+        public void permits(ConstraintsParameters cp)
+                throws CertPathValidatorException {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on disabled " +
+                            "algorithm: " + algorithm + extendedMsg(cp),
+                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
+        public boolean permits(Key key) {
+            return false;
+        }
+    }
 }
 
--- a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,25 +28,23 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.CodeSigner;
-import java.security.CryptoPrimitive;
+import java.security.GeneralSecurityException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SignatureException;
+import java.security.Timestamp;
 import java.security.cert.CertPath;
 import java.security.cert.X509Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.util.ArrayList;
 import java.util.Base64;
-import java.util.Collections;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 import java.util.jar.Attributes;
 import java.util.jar.JarException;
 import java.util.jar.JarFile;
@@ -61,9 +59,6 @@
     /* Are we debugging ? */
     private static final Debug debug = Debug.getInstance("jar");
 
-    private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
-            Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
-
     private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
             new DisabledAlgorithmConstraints(
                     DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
@@ -97,6 +92,14 @@
     /* for generating certpath objects */
     private CertificateFactory certificateFactory = null;
 
+    /** Algorithms that have been checked if they are weak. */
+    private Map<String, Boolean> permittedAlgs= new HashMap<>();
+
+    /** TSA timestamp of signed jar.  The newest timestamp is used.  If there
+     *  was no TSA timestamp used when signed, current time is used ("null").
+     */
+    private Timestamp timestamp = null;
+
     /**
      * Create the named SignatureFileVerifier.
      *
@@ -222,15 +225,8 @@
 
     /** get digest from cache */
 
-    private MessageDigest getDigest(String algorithm) throws SignatureException {
-        // check that algorithm is not restricted
-        if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, algorithm, null)) {
-            SignatureException e =
-                    new SignatureException("SignatureFile check failed. " +
-                            "Disabled algorithm used: " + algorithm);
-            throw e;
-        }
-
+    private MessageDigest getDigest(String algorithm)
+            throws SignatureException {
         if (createdDigests == null)
             createdDigests = new HashMap<>();
 
@@ -302,6 +298,27 @@
         if (newSigners == null)
             return;
 
+        /*
+         * Look for the latest timestamp in the signature block.  If an entry
+         * has no timestamp, use current time (aka null).
+         */
+        for (CodeSigner s: newSigners) {
+            if (debug != null) {
+                debug.println("Gathering timestamp for:  " + s.toString());
+            }
+            if (s.getTimestamp() == null) {
+                timestamp = null;
+                break;
+            } else if (timestamp == null) {
+                timestamp = s.getTimestamp();
+            } else {
+                if (timestamp.getTimestamp().before(
+                        s.getTimestamp().getTimestamp())) {
+                    timestamp = s.getTimestamp();
+                }
+            }
+        }
+
         Iterator<Map.Entry<String,Attributes>> entries =
                                 sf.getEntries().entrySet().iterator();
 
@@ -345,6 +362,68 @@
     }
 
     /**
+     * Check if algorithm is permitted using the permittedAlgs Map.
+     * If the algorithm is not in the map, check against disabled algorithms and
+     * store the result. If the algorithm is in the map use that result.
+     * False is returned for weak algorithm, true for good algorithms.
+     */
+    boolean permittedCheck(String key, String algorithm) {
+        Boolean permitted = permittedAlgs.get(algorithm);
+        if (permitted == null) {
+            try {
+                JAR_DISABLED_CHECK.permits(algorithm,
+                        new ConstraintsParameters(timestamp));
+            } catch(GeneralSecurityException e) {
+                permittedAlgs.put(algorithm, Boolean.FALSE);
+                permittedAlgs.put(key.toUpperCase(), Boolean.FALSE);
+                if (debug != null) {
+                    if (e.getMessage() != null) {
+                        debug.println(key + ":  " + e.getMessage());
+                    } else {
+                        debug.println(key + ":  " + algorithm +
+                                " was disabled, no exception msg given.");
+                        e.printStackTrace();
+                    }
+                }
+                return false;
+            }
+
+            permittedAlgs.put(algorithm, Boolean.TRUE);
+            return true;
+        }
+
+        // Algorithm has already been checked, return the value from map.
+        return permitted.booleanValue();
+    }
+
+    /**
+     * With a given header (*-DIGEST*), return a string that lists all the
+     * algorithms associated with the header.
+     * If there are none, return "Unknown Algorithm".
+     */
+    String getWeakAlgorithms(String header) {
+        String w = "";
+        try {
+            for (String key : permittedAlgs.keySet()) {
+                if (key.endsWith(header)) {
+                    w += key.substring(0, key.length() - header.length()) + " ";
+                }
+            }
+        } catch (RuntimeException e) {
+            w = "Unknown Algorithm(s).  Error processing " + header + ".  " +
+                    e.getMessage();
+        }
+
+        // This means we have an error in finding weak algorithms, run in
+        // debug mode to see permittedAlgs map's values.
+        if (w.length() == 0) {
+            return "Unknown Algorithm(s)";
+        }
+
+        return w;
+    }
+
+    /**
      * See if the whole manifest was signed.
      */
     private boolean verifyManifestHash(Manifest sf,
@@ -354,6 +433,7 @@
     {
         Attributes mattr = sf.getMainAttributes();
         boolean manifestSigned = false;
+        boolean weakAlgs = true;
 
         // go through all the attributes and process *-Digest-Manifest entries
         for (Map.Entry<Object,Object> se : mattr.entrySet()) {
@@ -364,6 +444,15 @@
                 // 16 is length of "-Digest-Manifest"
                 String algorithm = key.substring(0, key.length()-16);
 
+                // Check if this algorithm is permitted, skip if false.
+                if (!permittedCheck(key, algorithm)) {
+                    continue;
+                }
+
+                // A non-weak algorithm was used, any weak algorithms found do
+                // not need to be reported.
+                weakAlgs = false;
+
                 manifestDigests.add(key);
                 manifestDigests.add(se.getValue());
                 MessageDigest digest = getDigest(algorithm);
@@ -373,15 +462,14 @@
                         Base64.getMimeDecoder().decode((String)se.getValue());
 
                     if (debug != null) {
-                     debug.println("Signature File: Manifest digest " +
-                                          digest.getAlgorithm());
-                     debug.println( "  sigfile  " + toHex(expectedHash));
-                     debug.println( "  computed " + toHex(computedHash));
-                     debug.println();
+                        debug.println("Signature File: Manifest digest " +
+                                algorithm);
+                        debug.println( "  sigfile  " + toHex(expectedHash));
+                        debug.println( "  computed " + toHex(computedHash));
+                        debug.println();
                     }
 
-                    if (MessageDigest.isEqual(computedHash,
-                                              expectedHash)) {
+                    if (MessageDigest.isEqual(computedHash, expectedHash)) {
                         manifestSigned = true;
                     } else {
                         //XXX: we will continue and verify each section
@@ -389,15 +477,31 @@
                 }
             }
         }
+
+        if (debug != null) {
+            debug.println("PermittedAlgs mapping: ");
+            for (String key : permittedAlgs.keySet()) {
+                debug.println(key + " : " +
+                        permittedAlgs.get(key).toString());
+            }
+        }
+
+        // If there were only weak algorithms used, throw an exception.
+        if (weakAlgs) {
+            String weakAlgorithms = getWeakAlgorithms("-DIGEST-MANIFEST");
+            throw new SignatureException("Manifest hash check failed " +
+                    "(DIGEST-MANIFEST). Disabled algorithm(s) used: " +
+                    weakAlgorithms);
+        }
         return manifestSigned;
     }
 
-    private boolean verifyManifestMainAttrs(Manifest sf,
-                                        ManifestDigester md)
+    private boolean verifyManifestMainAttrs(Manifest sf, ManifestDigester md)
          throws IOException, SignatureException
     {
         Attributes mattr = sf.getMainAttributes();
         boolean attrsVerified = true;
+        boolean weakAlgs = true;
 
         // go through all the attributes and process
         // digest entries for the manifest main attributes
@@ -408,6 +512,15 @@
                 String algorithm =
                         key.substring(0, key.length() - ATTR_DIGEST.length());
 
+                // Check if this algorithm is permitted, skip if false.
+                if (!permittedCheck(key, algorithm)) {
+                    continue;
+                }
+
+                // A non-weak algorithm was used, any weak algorithms found do
+                // not need to be reported.
+                weakAlgs = false;
+
                 MessageDigest digest = getDigest(algorithm);
                 if (digest != null) {
                     ManifestDigester.Entry mde =
@@ -425,8 +538,7 @@
                      debug.println();
                     }
 
-                    if (MessageDigest.isEqual(computedHash,
-                                              expectedHash)) {
+                    if (MessageDigest.isEqual(computedHash, expectedHash)) {
                         // good
                     } else {
                         // we will *not* continue and verify each section
@@ -442,6 +554,23 @@
             }
         }
 
+        if (debug != null) {
+            debug.println("PermittedAlgs mapping: ");
+            for (String key : permittedAlgs.keySet()) {
+                debug.println(key + " : " +
+                        permittedAlgs.get(key).toString());
+            }
+        }
+
+        // If there were only weak algorithms used, throw an exception.
+        if (weakAlgs) {
+            String weakAlgorithms = getWeakAlgorithms("-DIGEST-" +
+                    ManifestDigester.MF_MAIN_ATTRS);
+            throw new SignatureException("Manifest Main Attribute check " +
+                    "failed (DIGEST-" + ManifestDigester.MF_MAIN_ATTRS +
+                    "). " + "Disabled algorithm(s) used: " + weakAlgorithms);
+        }
+
         // this method returns 'true' if either:
         //      . manifest main attributes were not signed, or
         //      . manifest main attributes were signed and verified
@@ -464,6 +593,7 @@
     {
         boolean oneDigestVerified = false;
         ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
+        boolean weakAlgs = true;
 
         if (mde == null) {
             throw new SecurityException(
@@ -471,7 +601,6 @@
         }
 
         if (sfAttr != null) {
-
             //sun.security.util.HexDumpEncoder hex = new sun.security.util.HexDumpEncoder();
             //hex.encodeBuffer(data, System.out);
 
@@ -483,6 +612,15 @@
                     // 7 is length of "-Digest"
                     String algorithm = key.substring(0, key.length()-7);
 
+                    // Check if this algorithm is permitted, skip if false.
+                    if (!permittedCheck(key, algorithm)) {
+                        continue;
+                    }
+
+                    // A non-weak algorithm was used, any weak algorithms found do
+                    // not need to be reported.
+                    weakAlgs = false;
+
                     MessageDigest digest = getDigest(algorithm);
 
                     if (digest != null) {
@@ -532,6 +670,23 @@
                 }
             }
         }
+
+        if (debug != null) {
+            debug.println("PermittedAlgs mapping: ");
+            for (String key : permittedAlgs.keySet()) {
+                debug.println(key + " : " +
+                        permittedAlgs.get(key).toString());
+            }
+        }
+
+        // If there were only weak algorithms used, throw an exception.
+        if (weakAlgs) {
+            String weakAlgorithms = getWeakAlgorithms("DIGEST");
+            throw new SignatureException("Manifest Main Attribute check " +
+                    "failed (DIGEST). " + "Disabled algorithm(s) used: " +
+                    weakAlgorithms);
+        }
+
         return oneDigestVerified;
     }
 
--- a/src/java.base/share/classes/sun/security/validator/PKIXValidator.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/validator/PKIXValidator.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 import javax.security.auth.x500.X500Principal;
 import sun.security.action.GetBooleanAction;
 import sun.security.provider.certpath.AlgorithmChecker;
-import sun.security.provider.certpath.PKIXTimestampParameters;
+import sun.security.provider.certpath.PKIXExtendedParameters;
 
 /**
  * Validator implementation built on the PKIX CertPath API. This
@@ -199,9 +199,9 @@
         PKIXBuilderParameters pkixParameters = null;
         if (parameter instanceof Timestamp && plugin) {
             try {
-                pkixParameters = new PKIXTimestampParameters(
+                pkixParameters = new PKIXExtendedParameters(
                         (PKIXBuilderParameters) parameterTemplate.clone(),
-                        (Timestamp) parameter);
+                        (Timestamp) parameter, variant);
             } catch (InvalidAlgorithmParameterException e) {
                 // ignore exception
             }
@@ -211,7 +211,8 @@
 
         // add new algorithm constraints checker
         if (constraints != null) {
-            pkixParameters.addCertPathChecker(new AlgorithmChecker(constraints));
+            pkixParameters.addCertPathChecker(
+                    new AlgorithmChecker(constraints, null, variant));
         }
 
         // attach it to the PKIXBuilderParameters.
--- a/src/java.base/share/classes/sun/security/validator/SimpleValidator.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/classes/sun/security/validator/SimpleValidator.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -155,12 +155,14 @@
 
         // create default algorithm constraints checker
         TrustAnchor anchor = new TrustAnchor(anchorCert, null);
-        AlgorithmChecker defaultAlgChecker = new AlgorithmChecker(anchor);
+        AlgorithmChecker defaultAlgChecker =
+                new AlgorithmChecker(anchor, variant);
 
         // create application level algorithm constraints checker
         AlgorithmChecker appAlgChecker = null;
         if (constraints != null) {
-            appAlgChecker = new AlgorithmChecker(anchor, constraints);
+            appAlgChecker = new AlgorithmChecker(anchor, constraints, null,
+                    variant);
         }
 
         // verify top down, starting at the certificate issued by
--- a/src/java.base/share/conf/security/java.security	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/conf/security/java.security	Thu Feb 09 18:10:19 2017 +0000
@@ -116,6 +116,13 @@
 # Example:
 #   jdk.security.provider.preferred=AES/GCM/NoPadding:SunJCE, \
 #         MessageDigest.SHA-256:SUN, Group.HmacSHA2:SunJCE
+#
+#ifdef solaris-sparc
+# Optional Solaris-SPARC configuration for non-FIPS 140 configurations.
+#   jdk.security.provider.preferred=AES:SunJCE, SHA1:SUN, Group.SHA2:SUN, \
+#   HmacSHA1:SunJCE, Group.HmacSHA2:SunJCE
+#
+#endif
 #jdk.security.provider.preferred=
 
 
@@ -240,6 +247,7 @@
 #
 # The default value is an empty string, which is equivalent to
 #   securerandom.drbg.config=Hash_DRBG,SHA-256,128,none
+#
 securerandom.drbg.config=
 
 #
@@ -262,23 +270,27 @@
 
 # The default is to have a single system-wide policy file,
 # and a policy file in the user's home directory.
+#
 policy.url.1=file:${java.home}/conf/security/java.policy
 policy.url.2=file:${user.home}/.java.policy
 
 # whether or not we expand properties in the policy file
 # if this is set to false, properties (${...}) will not be expanded in policy
 # files.
+#
 policy.expandProperties=true
 
 # whether or not we allow an extra policy to be passed on the command line
 # with -Djava.security.policy=somefile. Comment out this line to disable
 # this feature.
+#
 policy.allowSystemProperty=true
 
 # whether or not we look into the IdentityScope for trusted Identities
 # when encountering a 1.1 signed JAR file. If the identity is found
 # and is trusted, we grant it AllPermission. Note: the default policy
 # provider (sun.security.provider.PolicyFile) does not support this property.
+#
 policy.ignoreIdentityScope=false
 
 #
@@ -360,7 +372,6 @@
 # For this reason the default caching policy is to maintain these
 # results for 10 seconds.
 #
-#
 networkaddress.cache.negative.ttl=10
 
 #
@@ -460,8 +471,10 @@
 # Example,
 #   krb5.kdc.bad.policy = tryLast
 #   krb5.kdc.bad.policy = tryLess:2,2000
+#
 krb5.kdc.bad.policy = tryLast
 
+#
 # Algorithm restrictions for certification path (CertPath) processing
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -481,7 +494,8 @@
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint | CAConstraint | DenyAfterConstraint
+#       KeySizeConstraint | CAConstraint | DenyAfterConstraint |
+#       UsageConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator KeyLength
@@ -498,6 +512,9 @@
 #   DenyAfterConstraint:
 #       denyAfter YYYY-MM-DD
 #
+#   UsageConstraint:
+#       usage [TLSServer] [TLSClient] [SignedJAR]
+#
 # The "AlgorithmName" is the standard algorithm name of the disabled
 # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
 # Documentation" for information about Standard Algorithm Names.  Matching
@@ -547,6 +564,19 @@
 #       Example:  To deny usage of RSA 2048 bit certificates after Feb 3 2020,
 #       use the following:  "RSA keySize == 2048 & denyAfter 2020-02-03"
 #
+#   UsageConstraint:
+#     usage [TLSServer] [TLSClient] [SignedJAR]
+#       This constraint prohibits the specified algorithm for
+#       a specified usage.  This should be used when disabling an algorithm
+#       for all usages is not practical. 'TLSServer' restricts the algorithm
+#       in TLS server certificate chains when server authentication is
+#       performed. 'TLSClient' restricts the algorithm in TLS client
+#       certificate chains when client authentication is performed.
+#       'SignedJAR' constrains use of certificates in signed jar files.
+#       The usage type follows the keyword and more than one usage type can
+#       be specified with a whitespace delimiter.
+#       Example:  "SHA1 usage TLSServer TLSClient"
+#
 # When an algorithm must satisfy more than one constraint, it must be
 # delimited by an ampersand '&'.  For example, to restrict certificates in a
 # chain that terminate at a distribution provided trust anchor and contain
@@ -572,35 +602,6 @@
     RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
 
 #
-# RMI Registry Serial Filter
-#
-# The filter pattern uses the same format as jdk.serialFilter.
-# This filter can override the builtin filter if additional types need to be
-# allowed or rejected from the RMI Registry.
-#
-# Note: This property is currently used by the JDK Reference implementation.
-# It is not guaranteed to be examined and used by other implementations.
-#
-#sun.rmi.registry.registryFilter=pattern;pattern
-#
-# RMI Distributed Garbage Collector (DGC) Serial Filter
-#
-# The filter pattern uses the same format as jdk.serialFilter.
-# This filter can override the builtin filter if additional types need to be
-# allowed or rejected from the RMI DGC.
-#
-# Note: This property is currently used by the JDK Reference implementation.
-# It is not guaranteed to be examined and used by other implementations.
-#
-# The builtin DGC filter can approximately be represented as the filter pattern:
-#
-#sun.rmi.transport.dgcFilter=\
-#    java.rmi.server.ObjID;\
-#    java.rmi.server.UID;\
-#    java.rmi.dgc.VMID;\
-#    java.rmi.dgc.Lease;\
-#    maxdepth=5;maxarray=10000
-
 # Algorithm restrictions for signed JAR files
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -615,17 +616,20 @@
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
 #   DisabledAlgorithm:
-#       AlgorithmName [Constraint]
+#       AlgorithmName [Constraint] { '&' Constraint }
 #
 #   AlgorithmName:
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint
+#       KeySizeConstraint | DenyAfterConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator KeyLength
 #
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
+#
 #   Operator:
 #       <= | < | == | != | >= | >
 #
@@ -636,9 +640,12 @@
 # implementation. It is not guaranteed to be examined and used by other
 # implementations.
 #
+# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
+#
 jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
       DSA keySize < 1024
 
+#
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS/DTLS) processing
 #
@@ -939,3 +946,32 @@
 #
 #jdk.serialFilter=pattern;pattern
 
+#
+# RMI Registry Serial Filter
+#
+# The filter pattern uses the same format as jdk.serialFilter.
+# This filter can override the builtin filter if additional types need to be
+# allowed or rejected from the RMI Registry.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+#sun.rmi.registry.registryFilter=pattern;pattern
+#
+# RMI Distributed Garbage Collector (DGC) Serial Filter
+#
+# The filter pattern uses the same format as jdk.serialFilter.
+# This filter can override the builtin filter if additional types need to be
+# allowed or rejected from the RMI DGC.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# The builtin DGC filter can approximately be represented as the filter pattern:
+#
+#sun.rmi.transport.dgcFilter=\
+#    java.rmi.server.ObjID;\
+#    java.rmi.server.UID;\
+#    java.rmi.dgc.VMID;\
+#    java.rmi.dgc.Lease;\
+#    maxdepth=5;maxarray=10000
--- a/src/java.base/share/lib/security/default.policy	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/lib/security/default.policy	Thu Feb 09 18:10:19 2017 +0000
@@ -102,6 +102,8 @@
 };
 
 grant codeBase "jrt:/java.xml.ws" {
+    permission java.net.NetPermission
+                   "getProxySelector";
     permission java.lang.RuntimePermission
                    "accessClassInPackage.com.sun.org.apache.xml.internal.resolver";
     permission java.lang.RuntimePermission
--- a/src/java.base/share/native/launcher/main.c	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/native/launcher/main.c	Thu Feb 09 18:10:19 2017 +0000
@@ -130,10 +130,10 @@
 
         // Add first arg, which is the app name
         JLI_List_add(args, JLI_StringDup(argv[0]));
-        // Append JAVA_OPTIONS
-        if (JLI_AddArgsFromEnvVar(args, JAVA_OPTIONS)) {
+        // Append JDK_JAVA_OPTIONS
+        if (JLI_AddArgsFromEnvVar(args, JDK_JAVA_OPTIONS)) {
             // JLI_SetTraceLauncher is not called yet
-            // Show _JAVA_OPTIONS content along with JAVA_OPTIONS to aid diagnosis
+            // Show _JAVA_OPTIONS content along with JDK_JAVA_OPTIONS to aid diagnosis
             if (getenv(JLDEBUG_ENV_ENTRY)) {
                 char *tmp = getenv("_JAVA_OPTIONS");
                 if (NULL != tmp) {
--- a/src/java.base/share/native/libjli/args.c	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/native/libjli/args.c	Thu Feb 09 18:10:19 2017 +0000
@@ -34,7 +34,7 @@
     #define NO_JNI
   #endif
   #define JLI_ReportMessage(...) printf(__VA_ARGS__)
-  #define JAVA_OPTIONS "JAVA_OPTIONS"
+  #define JDK_JAVA_OPTIONS "JDK_JAVA_OPTIONS"
   int IsWhiteSpaceOption(const char* name) { return 1; }
 #else
   #include "java.h"
@@ -429,10 +429,6 @@
 }
 
 jboolean JLI_AddArgsFromEnvVar(JLI_List args, const char *var_name) {
-
-#ifndef ENABLE_JAVA_OPTIONS
-    return JNI_FALSE;
-#else
     char *env = getenv(var_name);
     char *p, *arg;
     char quote;
@@ -519,7 +515,6 @@
     }
 
     return JNI_TRUE;
-#endif
 }
 
 #ifdef DEBUG_ARGFILE
--- a/src/java.base/share/native/libjli/java.h	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/share/native/libjli/java.h	Thu Feb 09 18:10:19 2017 +0000
@@ -71,7 +71,7 @@
 
 #define SPLASH_FILE_ENV_ENTRY "_JAVA_SPLASH_FILE"
 #define SPLASH_JAR_ENV_ENTRY "_JAVA_SPLASH_JAR"
-#define JAVA_OPTIONS "JAVA_OPTIONS"
+#define JDK_JAVA_OPTIONS "JDK_JAVA_OPTIONS"
 
 /*
  * Pointers to the needed JNI invocation API, initialized by LoadJavaVM.
--- a/src/java.base/windows/native/libjli/cmdtoargs.c	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.base/windows/native/libjli/cmdtoargs.c	Thu Feb 09 18:10:19 2017 +0000
@@ -205,9 +205,9 @@
     size_t i, cnt;
 
     JLI_List envArgs = JLI_List_new(1);
-    if (JLI_AddArgsFromEnvVar(envArgs, JAVA_OPTIONS)) {
+    if (JLI_AddArgsFromEnvVar(envArgs, JDK_JAVA_OPTIONS)) {
         // JLI_SetTraceLauncher is not called yet
-        // Show _JAVA_OPTIONS content along with JAVA_OPTIONS to aid diagnosis
+        // Show _JAVA_OPTIONS content along with JDK_JAVA_OPTIONS to aid diagnosis
         if (getenv(JLDEBUG_ENV_ENTRY)) {
             char *tmp = getenv("_JAVA_OPTIONS");
             if (NULL != tmp) {
--- a/src/java.rmi/share/classes/java/rmi/activation/ActivationInstantiator.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.rmi/share/classes/java/rmi/activation/ActivationInstantiator.java	Thu Feb 09 18:10:19 2017 +0000
@@ -60,7 +60,20 @@
     * initialization data, and
     *
     * <li> returning a MarshalledObject containing the stub for the
-    * remote object it created </ul>
+    * remote object it created.</ul>
+    *
+    * <p>In order for activation to be successful, one of the following requirements
+    * must be met, otherwise {@link ActivationException} is thrown:
+    *
+    * <ul><li>The class to be activated and the special activation constructor are both public,
+    * and the class resides in a package that is
+    * {@linkplain java.lang.reflect.Module#isExported(String,java.lang.reflect.Module) exported}
+    * to at least the {@code java.rmi} module; or
+    *
+    * <li>The class to be activated resides in a package that is
+    * {@linkplain java.lang.reflect.Module#isOpen(String,java.lang.reflect.Module) open}
+    * to at least the {@code java.rmi} module.
+    * </ul>
     *
     * @param id the object's activation identifier
     * @param desc the object's descriptor
--- a/src/java.rmi/share/classes/java/rmi/activation/Activator.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.rmi/share/classes/java/rmi/activation/Activator.java	Thu Feb 09 18:10:19 2017 +0000
@@ -48,7 +48,7 @@
  * The <code>Activator</code> works closely with
  * <code>ActivationSystem</code>, which provides a means for registering
  * groups and objects within those groups, and <code>ActivationMonitor</code>,
- * which recives information about active and inactive objects and inactive
+ * which receives information about active and inactive objects and inactive
  * groups. <p>
  *
  * The activator is responsible for monitoring and detecting when
--- a/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java	Thu Feb 09 18:10:19 2017 +0000
@@ -107,8 +107,9 @@
  * the binary name of the root class with the suffix {@code _Stub}.
  *
  * <li>The stub class is loaded by name using the class loader of the root
- * class. The stub class must extend {@link RemoteStub} and must have a
- * public constructor that has one parameter of type {@link RemoteRef}.
+ * class. The stub class must be public, it must extend {@link RemoteStub}, it must
+ * reside in a package that is exported to at least the {@code java.rmi} module, and it
+ * must have a public constructor that has one parameter of type {@link RemoteRef}.
  *
  * <li>Finally, an instance of the stub class is constructed with a
  * {@link RemoteRef}.
@@ -124,12 +125,21 @@
  *
  * <ul>
  *
- * <li>The proxy's class is defined by the class loader of the remote
- * object's class.
+ * <li>The proxy's class is defined according to the specifications for the
+ * <a href="{@docRoot}/java/lang/reflect/Proxy.html#membership">
+ * {@code Proxy}
+ * </a>
+ * class, using the class loader of the remote object's class.
  *
  * <li>The proxy implements all the remote interfaces implemented by the
  * remote object's class.
  *
+ * <li>Each remote interface must either be public and reside in a package that is
+ * {@linkplain java.lang.reflect.Module#isExported(String,java.lang.reflect.Module) exported}
+ * to at least the {@code java.rmi} module, or it must reside in a package that is
+ * {@linkplain java.lang.reflect.Module#isOpen(String,java.lang.reflect.Module) open}
+ * to at least the {@code java.rmi} module.
+ *
  * <li>The proxy's invocation handler is a {@link
  * RemoteObjectInvocationHandler} instance constructed with a
  * {@link RemoteRef}.
--- a/src/jdk.crypto.ucrypto/solaris/conf/security/ucrypto-solaris.cfg	Thu Feb 09 17:21:47 2017 +0000
+++ b/src/jdk.crypto.ucrypto/solaris/conf/security/ucrypto-solaris.cfg	Thu Feb 09 18:10:19 2017 +0000
@@ -2,8 +2,5 @@
 # Configuration file for the OracleUcrypto provider
 #
 disabledServices = {
-  # disabled due to Solaris bug 7121679
-  Cipher.AES/CFB128/PKCS5Padding
-  Cipher.AES/CFB128/NoPadding
 }
 
--- a/test/ProblemList.txt	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/ProblemList.txt	Thu Feb 09 18:10:19 2017 +0000
@@ -251,7 +251,6 @@
 
 tools/pack200/CommandLineTests.java                             8059906 generic-all
 
-tools/launcher/ArgsEnvVar.java					8173712 generic-all
 tools/launcher/FXLauncherTest.java                              8068049 linux-all,macosx-all
 
 tools/jimage/JImageExtractTest.java                             8169713 generic-all
--- a/test/TEST.groups	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/TEST.groups	Thu Feb 09 18:10:19 2017 +0000
@@ -273,6 +273,7 @@
     jdk/internal/jline \
     com/sun/jndi \
     com/sun/corba \
+    org/omg/CORBA \
     lib/testlibrary \
     sample
 
--- a/test/com/oracle/security/ucrypto/TestAES.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/com/oracle/security/ucrypto/TestAES.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7088989 8014374 8167512
+ * @bug 7088989 8014374 8167512 8173708
  * @summary Ensure the AES ciphers of OracleUcrypto provider works correctly
  * @key randomness
  * @run main TestAES
@@ -177,6 +177,12 @@
                     k += c.doFinal(eout, firstPartLen+1, eout.length - firstPartLen - 1, dout, k);
                     if (!checkArrays(in, in.length, dout, k)) testPassed = false;
                 } catch(Exception ex) {
+                    if (ex instanceof BadPaddingException &&
+                            algos[i].indexOf("CFB128") != -1 &&
+                            p.getName().equals("OracleUcrypto")) {
+                        System.out.println("Ignore due to a pre-S11.3 bug: " + ex);
+                        continue;
+                    }
                     System.out.println("Unexpected Exception: " + algos[i]);
                     ex.printStackTrace();
                     testPassed = false;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/ClassLoader/securityManager/ClassLoaderTest.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8168423
+ * @summary Different types of ClassLoader running with(out) SecurityManager and
+ *          (in)valid security policy file.
+ * @library /lib/testlibrary
+ * @modules java.base/jdk.internal.module
+ * @build JarUtils CompilerUtils
+ * @run main/timeout=240 ClassLoaderTest
+ */
+import java.io.File;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.module.ModuleDescriptor;
+import jdk.internal.module.ModuleInfoWriter;
+import jdk.testlibrary.ProcessTools;
+
+public class ClassLoaderTest {
+
+    private static final String SRC = System.getProperty("test.src");
+    private static final Path CL_SRC = Paths.get(SRC, "TestClassLoader.java");
+    private static final Path C_SRC = Paths.get(SRC, "TestClient.java");
+    private static final Path CL_BIN = Paths.get("classes", "clbin");
+    private static final Path C_BIN = Paths.get("classes", "cbin");
+    private static final Path ARTIFACT_DIR = Paths.get("jars");
+    private static final Path VALID_POLICY = Paths.get(SRC, "valid.policy");
+    private static final Path INVALID_POLICY
+            = Paths.get(SRC, "malformed.policy");
+    private static final Path NO_POLICY = null;
+    private static final String LOCALE = "-Duser.language=en -Duser.region=US";
+    /*
+     * Here is the naming convention followed for each jar.
+     * cl.jar   - Regular custom class loader jar.
+     * mcl.jar  - Modular custom class loader jar.
+     * c.jar    - Regular client jar.
+     * mc.jar   - Modular client jar.
+     * amc.jar  - Modular client referring automated custom class loader jar.
+     */
+    private static final Path CL_JAR = ARTIFACT_DIR.resolve("cl.jar");
+    private static final Path MCL_JAR = ARTIFACT_DIR.resolve("mcl.jar");
+    private static final Path C_JAR = ARTIFACT_DIR.resolve("c.jar");
+    private static final Path MC_JAR = ARTIFACT_DIR.resolve("mc.jar");
+    private static final Path AMC_JAR = ARTIFACT_DIR.resolve("amc.jar");
+    private static final Map<String, String> MSG_MAP = new HashMap<>();
+
+    static {
+        // This mapping help process finding expected message based
+        // on the key passed as argument while executing java command.
+        MSG_MAP.put("MissingModule", "Module cl not found, required by mc");
+        MSG_MAP.put("ErrorPolicy", "java.security.policy: error parsing file");
+        MSG_MAP.put(
+                "SystemCL", "jdk.internal.loader.ClassLoaders$AppClassLoader");
+        MSG_MAP.put("CustomCL", "cl.TestClassLoader");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        // Generates regular and modular jars before start processing it.
+        setUp();
+        processForEachPolicyFile();
+    }
+
+    /**
+     * Test cases are based on the following logic,
+     *  for (policyFile : {"NO_POLICY", "VALID", "MALFORMED"}) {
+     *      for (classLoader : {"SystemClassLoader", "CustomClassLoader"}){
+     *          for (clientModule : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
+     *              for (classLoaderModule : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
+     *                  Create and run java command for each possible Test case
+     *              }
+     *          }
+     *      }
+     *  }
+     */
+    private static void processForEachPolicyFile() throws Exception {
+
+        final String regCLloc = CL_JAR.toFile().getAbsolutePath();
+        final String modCLloc = MCL_JAR.toFile().getAbsolutePath();
+        final String regCloc = C_JAR.toFile().getAbsolutePath();
+        final String modCloc = MC_JAR.toFile().getAbsolutePath();
+        final String autoModCloc = AMC_JAR.toFile().getAbsolutePath();
+        final String separator = File.pathSeparator;
+
+        for (Path policy
+                : new Path[]{NO_POLICY, VALID_POLICY, INVALID_POLICY}) {
+            final String policyFile = (policy != null)
+                    ? policy.toFile().getAbsolutePath() : null;
+            final boolean malformedPolicy
+                    = (policy == null) ? false : policy.equals(INVALID_POLICY);
+
+            for (boolean useSCL : new boolean[]{true, false}) {
+                final String clVmArg = (useSCL) ? ""
+                        : "-Djava.system.class.loader=cl.TestClassLoader";
+                final String autoAddModArg
+                        = (useSCL) ? "" : "--add-modules=cl";
+                final String addmodArg = (useSCL) ? "" : "--add-modules=mcl";
+                final String sMArg = (policy != null) ? String.format(
+                        "-Djava.security.manager -Djava.security.policy=%s",
+                        policyFile) : "";
+                final String smMsg = (policy != null) ? "With SecurityManager"
+                        : "Without SecurityManager";
+                final String expectedResult = ((!malformedPolicy)
+                        ? ((useSCL) ? "PASS SystemCL" : "PASS CustomCL")
+                        : "FAIL ErrorPolicy");
+
+                // NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED
+                System.out.printf("Case:- Modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s -m mc/c.TestClient",
+                    modCloc, separator, modCLloc, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+                System.out.printf("Case:- Modular Client and %s %s%n", ((useSCL)
+                        ? "SystemClassLoader"
+                        : "Automatic modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s -m mc/c.TestClient",
+                    autoModCloc, separator, regCLloc, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+                System.out.printf("Case:- Modular Client and %s %s%n", ((useSCL)
+                        ? "SystemClassLoader"
+                        : "Unknown modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s -cp %s %s %s %s -m mc/c.TestClient",
+                    autoModCloc, regCLloc, LOCALE, clVmArg, sMArg),
+                    "FAIL MissingModule"});
+
+                // AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED
+                System.out.printf("Case:- Automated modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s %s -m c/c.TestClient",
+                    regCloc, separator, modCLloc, addmodArg, LOCALE, clVmArg,
+                    sMArg), expectedResult});
+                System.out.printf("Case:- Automated modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Automatic modular CustomClassLoader"),
+                        smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s %s -m c/c.TestClient",
+                    regCloc, separator, regCLloc, autoAddModArg, LOCALE,
+                    clVmArg, sMArg), expectedResult});
+                System.out.printf("Case:- Automated modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Unknown modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s -cp %s %s %s %s -m c/c.TestClient",
+                    regCloc, regCLloc, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+
+                // UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED
+                System.out.printf("Case:- Unknown modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "-cp %s --module-path %s %s %s %s %s c.TestClient",
+                    regCloc, modCLloc, addmodArg, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+                System.out.printf("Case:- Unknown modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Automatic modular CustomClassLoader"),
+                        smMsg);
+                execute(new String[]{String.format(
+                    "-cp %s --module-path %s %s %s %s %s c.TestClient",
+                    regCloc, regCLloc, autoAddModArg, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+                System.out.printf("Case:- Unknown modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Unknown modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "-cp %s%s%s %s %s %s c.TestClient", regCloc, separator,
+                    regCLloc, LOCALE, clVmArg, sMArg), expectedResult});
+
+                // Regular jars in module-path and Modular jars in class-path.
+                System.out.printf("Case:- Regular Client and %s "
+                        + "inside --module-path %s.%n", ((useSCL)
+                                ? "SystemClassLoader"
+                                : "Unknown modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s %s -m c/c.TestClient",
+                    regCloc, separator, regCLloc, autoAddModArg, LOCALE,
+                    clVmArg, sMArg), expectedResult});
+                System.out.printf("Case:- Modular Client and %s in -cp %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "-cp %s%s%s %s %s %s c.TestClient", modCloc, separator,
+                    modCLloc, LOCALE, clVmArg, sMArg), expectedResult});
+            }
+        }
+    }
+
+    /**
+     * Execute with command arguments and process the result.
+     */
+    private static void execute(String[] args) throws Exception {
+
+        String status = null;
+        String msgKey = null;
+        if ((args != null && args.length > 1)) {
+            String[] secArgs = args[1].split("\\s+");
+            status = (secArgs.length > 0) ? secArgs[0] : null;
+            msgKey = (secArgs.length > 1) ? secArgs[1] : null;
+        }
+        String out = ProcessTools.executeTestJvm(args[0].split("\\s+"))
+                .getOutput();
+        // Handle response.
+        if ((status != null && "PASS".equals(status) && msgKey != null
+                && out.contains(MSG_MAP.get(msgKey)))) {
+            System.out.printf("PASS: Expected Result: %s.%n",
+                    MSG_MAP.get(msgKey));
+        } else if ((status != null && "FAIL".equals(status) && msgKey != null
+                && out.contains(MSG_MAP.get(msgKey)))) {
+            System.out.printf("PASS: Expected Failure: %s.%n",
+                    MSG_MAP.get(msgKey));
+        } else if (out.contains("Exception") || out.contains("Error")) {
+            System.out.printf("OUTPUT: %s", out);
+            throw new RuntimeException("FAIL: Unknown Exception.");
+        } else {
+            System.out.printf("OUTPUT: %s", out);
+            throw new RuntimeException("FAIL: Unknown Test case found");
+        }
+    }
+
+    /**
+     * Creates regular/modular jar files for TestClient and TestClassLoader.
+     */
+    private static void setUp() throws Exception {
+
+        boolean compiled = CompilerUtils.compile(CL_SRC, CL_BIN);
+        compiled &= CompilerUtils.compile(C_SRC, C_BIN);
+        if (!compiled) {
+            throw new RuntimeException("Test Setup failed.");
+        }
+        // Generate regular jar files for TestClient and TestClassLoader
+        JarUtils.createJarFile(CL_JAR, CL_BIN);
+        JarUtils.createJarFile(C_JAR, C_BIN);
+        // Generate modular jar files for TestClient and TestClassLoader with
+        // their corresponding ModuleDescriptor.
+        Files.copy(CL_JAR, MCL_JAR, StandardCopyOption.REPLACE_EXISTING);
+        updateModuleDescr(MCL_JAR, ModuleDescriptor.module("mcl")
+                .exports("cl").requires("java.base").build());
+        Files.copy(C_JAR, MC_JAR, StandardCopyOption.REPLACE_EXISTING);
+        updateModuleDescr(MC_JAR, ModuleDescriptor.module("mc")
+                .exports("c").requires("java.base").requires("mcl").build());
+        Files.copy(C_JAR, AMC_JAR, StandardCopyOption.REPLACE_EXISTING);
+        updateModuleDescr(AMC_JAR, ModuleDescriptor.module("mc")
+                .exports("c").requires("java.base").requires("cl").build());
+    }
+
+    /**
+     * Update regular jars and include module-info.class inside it to make
+     * modular jars.
+     */
+    private static void updateModuleDescr(Path jar, ModuleDescriptor mDescr)
+            throws Exception {
+        if (mDescr != null) {
+            Path dir = Files.createTempDirectory("tmp");
+            Path mi = dir.resolve("module-info.class");
+            try (OutputStream out = Files.newOutputStream(mi)) {
+                ModuleInfoWriter.write(mDescr, out);
+            }
+            System.out.format("Adding 'module-info.class' to jar '%s'%n", jar);
+            JarUtils.updateJarFile(jar, dir);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/ClassLoader/securityManager/TestClassLoader.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 cl;
+
+public class TestClassLoader extends ClassLoader {
+
+    /**
+     * This constructor is used to set the parent ClassLoader
+     */
+    public TestClassLoader(ClassLoader parent) {
+        super(parent);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/ClassLoader/securityManager/TestClient.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 c;
+
+public class TestClient {
+
+    public static void main(String[] args) {
+
+        // Initialize policy file.
+        System.getProperty("test.src");
+        System.out.printf("ContextClassLoader: %s%n",
+                Thread.currentThread().getContextClassLoader().toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/ClassLoader/securityManager/malformed.policy	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,4 @@
+grant {
+    xyz;
+    permission java.util.PropertyPermission "test.src", "read";
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/ClassLoader/securityManager/valid.policy	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,4 @@
+grant codeBase "file:./jars/*" {
+    permission java.lang.RuntimePermission "createClassLoader";
+    permission java.util.PropertyPermission "test.src", "read";
+};
\ No newline at end of file
--- a/test/java/lang/StackWalker/Basic.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/java/lang/StackWalker/Basic.java	Thu Feb 09 18:10:19 2017 +0000
@@ -23,18 +23,21 @@
 
 /*
  * @test
- * @bug 8140450
+ * @bug 8140450 8173898
  * @summary Basic test for the StackWalker::walk method
  * @run testng Basic
  */
 
 import java.lang.StackWalker.StackFrame;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import static java.lang.StackWalker.Option.*;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import static org.testng.Assert.*;
 
 public class Basic {
     private static boolean verbose = false;
@@ -60,6 +63,17 @@
         }
     }
 
+    @Test
+    public static void testWalkFromConstructor() throws Exception {
+        System.out.println("testWalkFromConstructor:");
+        List<String> found = ((ConstructorNewInstance)ConstructorNewInstance.class.getMethod("create")
+                             .invoke(null)).collectedFrames();
+        assertEquals(List.of(ConstructorNewInstance.class.getName()+"::<init>",
+                             ConstructorNewInstance.class.getName()+"::create",
+                             Basic.class.getName()+"::testWalkFromConstructor"),
+                     found);
+    }
+
     private final int depth;
     Basic(int depth) {
         this.depth = depth;
@@ -77,6 +91,47 @@
         assertEquals(limit, frames.size());
     }
 
+    static class ConstructorNewInstance {
+        static final StackWalker walker =
+            StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+        List<String> testFramesOrReflectionFrames;
+        public ConstructorNewInstance() {
+            testFramesOrReflectionFrames = walker.walk(this::parse);
+        }
+        public List<String> collectedFrames() {
+            return testFramesOrReflectionFrames;
+        }
+        public boolean accept(StackFrame f) {
+            // Frames whose class names don't contain "."
+            // are our own test frames. These are the ones
+            // we expect.
+            // Frames whose class names contain ".reflect."
+            // are reflection frames. None should be present,
+            // since they are supposed to be filtered by
+            // by StackWalker. If we find any, we want to fail.
+            if (!f.getClassName().contains(".")
+                || f.getClassName().contains(".reflect.")) {
+                System.out.println("    " + f);
+                return true;
+            }
+            // Filter out all other frames (in particular
+            // those from the test framework) in order to
+            // have predictable results.
+            return false;
+        }
+        public String frame(StackFrame f) {
+            return f.getClassName() + "::" + f.getMethodName();
+        }
+        List<String> parse(Stream<StackFrame> s) {
+            return s.filter(this::accept)
+                    .map(this::frame)
+                    .collect(Collectors.toList());
+        }
+        public static ConstructorNewInstance create() throws Exception {
+            return ConstructorNewInstance.class.getConstructor().newInstance();
+        }
+    }
+
     class StackBuilder {
         private final int stackDepth;
         private final int limit;
@@ -131,9 +186,4 @@
         }
     }
 
-    static void assertEquals(int x, int y) {
-        if (x != y) {
-            throw new RuntimeException(x + " != " + y);
-        }
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/StackWalker/ReflectionFrames.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,842 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8173898
+ * @summary Basic test for checking filtering of reflection frames
+ * @run testng ReflectionFrames
+ */
+
+import java.lang.StackWalker.StackFrame;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static java.lang.StackWalker.Option.*;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class ReflectionFrames {
+    final static boolean verbose = false;
+
+    /**
+     * This test invokes new StackInspector() directly from
+     * the caller StackInspector.Caller.create method.
+     * It checks that the caller is StackInspector.Caller.
+     * It also checks the expected frames collected
+     * by walking the stack from the default StackInspector()
+     * constructor.
+     * This is done twice, once using a default StackWalker
+     * that hides reflection frames, once using a StackWalker
+     * configured to show reflection frames.
+     */
+    @Test
+    public static void testNewStackInspector() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes new StackInspector() directly.
+        // No reflection frame should appear.
+        System.out.println("testNewStackInspector: create");
+
+        StackInspector obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes new StackInspector() directly.
+        // No reflection frame should appear.
+        System.out.println("testNewStackInspector: reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // a MethodHandle.
+        // The create method invokes new StackInspector() directly.
+        // No reflection frame should appear.
+        System.out.println("testNewStackInspector: handle");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes new StackInspector() directly.
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewStackInspector: create: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes new StackInspector() directly.
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewStackInspector: reflect: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // MethodHandle.
+        // The create method invokes new StackInspector() directly.
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewStackInspector: handle: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             // MethodHandle::invoke remains hidden
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+    }
+
+   /**
+     * This test invokes Constructor.newInstance() from
+     * the caller StackInspector.Caller.create method.
+     * It checks that the caller is StackInspector.Caller.
+     * It also checks the expected frames collected
+     * by walking the stack from the default StackInspector()
+     * constructor.
+     * This is done twice, once using a default StackWalker
+     * that hides reflection frames, once using a StackWalker
+     * configured to show reflection frames.
+     */
+    @Test
+    public static void testConstructor() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes Constructor.newInstance().
+        // No reflection frame should appear.
+        System.out.println("testConstructor: create");
+
+        StackInspector obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes Constructor.newInstance().
+        // No reflection frame should appear.
+        System.out.println("testConstructor: reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // MethodHandle.
+        // The create method invokes Constructor.newInstance().
+        // No reflection frame should appear.
+        System.out.println("testConstructor: handle");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes Constructor.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testConstructor: create: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes Constructor.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testConstructor: reflect: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // MethodHandle.
+        // The create method invokes Constructor.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testConstructor: handle: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             // MethodHandle::invoke remains hidden
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+    }
+
+   /**
+     * This test invokes StackInspector.class.newInstance() from
+     * the caller StackInspector.Caller.create method. Because
+     * Class.newInstance() is not considered as a
+     * reflection frame, the the caller returned by
+     * getCallerClass() should appear to be java.lang.Class
+     * and not StackInspector.Caller.
+     * It also checks the expected frames collected
+     * by walking the stack from the default StackInspector()
+     * constructor.
+     * This is done twice, once using a default StackWalker
+     * that hides reflection frames, once using a StackWalker
+     * configured to show reflection frames.
+     */
+    @Test
+    public static void testNewInstance() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes StackInspector.class.newInstance().
+        // No reflection frame should appear, except
+        // Class::newInstance which is not considered as
+        // a reflection frame.
+        System.out.println("testNewInstance: create");
+
+        StackInspector obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes StackInspector.class.newInstance().
+        // No reflection frame should appear, except
+        // Class::newInstance which is not considered as
+        // a reflection frame.
+        System.out.println("testNewInstance: reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // reflection.
+        // The create method invokes StackInspector.class.newInstance().
+        // No reflection frame should appear, except
+        // Class::newInstance which is not considered as
+        // a reflection frame.
+        System.out.println("testNewInstance: handle");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertEquals(obj.filtered, 0);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes StackInspector.class.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewInstance: create: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes StackInspector.class.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewInstance: reflect: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // MethodHandle.
+        // The create method invokes StackInspector.class.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewInstance: handle: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             // MethodHandle::invoke remains hidden
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertNotEquals(obj.filtered, 0);
+    }
+
+    @Test
+    public static void testGetCaller() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        assertEquals(StackInspector.getCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),
+                     ReflectionFrames.class);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        assertEquals(StackInspector.getCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),
+                     ReflectionFrames.class);
+    }
+
+    @Test
+    public static void testReflectCaller() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),
+                     ReflectionFrames.class);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),
+                     ReflectionFrames.class);
+    }
+
+    @Test
+    public static void testSupplyCaller() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),
+                     ReflectionFrames.class);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),
+                     ReflectionFrames.class);
+    }
+
+    @Test
+    public static void testHandleCaller() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),
+                     ReflectionFrames.class);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),
+                     ReflectionFrames.class);
+    }
+
+    static enum How { NEW, CONSTRUCTOR, CLASS};
+
+    /**
+     * An object that collect stack frames by walking the stack
+     * (and calling getCallerClass()) from within its constructor.
+     * For the purpose of this test, StackInspector objects are
+     * always created from the nested StackInspector.Caller class,
+     * which should therefore appear as the caller of the
+     * StackInspector constructor.
+     */
+    static class StackInspector {
+        static final StackWalker walkerHide =
+            StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+        static final StackWalker walkerShow =
+            StackWalker.getInstance(EnumSet.of(
+                           StackWalker.Option.RETAIN_CLASS_REFERENCE,
+                           StackWalker.Option.SHOW_REFLECT_FRAMES));
+        final static ThreadLocal<StackWalker> walker = new ThreadLocal<>() {
+             protected StackWalker initialValue() {
+                 return walkerHide;
+             }
+        };
+
+        List<String> collectedFrames;
+        Class<?> cls = null;
+        boolean stop;
+        int filtered;
+        final boolean filterImplFrames;
+
+        public StackInspector() {
+            stop = false;
+            // if reflection frames are not hidden, we want to
+            // filter implementation frames before collecting
+            // to avoid depending on internal details.
+            filterImplFrames = walker.get() == walkerShow;
+            collectedFrames = walker.get().walk(this::parse);
+            cls = walker.get().getCallerClass();
+        }
+
+        public List<String> collectedFrames() {
+            return collectedFrames;
+        }
+
+        // The takeWhile method arrange for stopping frame collection
+        // as soon as a frame from ReflectionFrames.class is reached.
+        // The first such frame encountered is still included in the
+        // collected frames, but collection stops right after.
+        // This makes it possible to filter out anything above the
+        // the test method frame, such as frames from the test
+        // framework.
+        public boolean takeWhile(StackFrame f) {
+            if (stop) return false;
+            if (verbose) System.out.println("    " + f);
+            stop = stop || f.getDeclaringClass() == ReflectionFrames.class;
+            return true;
+        }
+
+        // filter out implementation frames to avoid depending
+        // on implementation details. If present, Class::newInstance,
+        // Method::invoke and Constructor::newInstance will
+        // still appear in the collected frames, which is
+        // sufficient for the purpose of the test.
+        // In the case where the StackWalker itself is supposed to
+        // filter the reflection frames, then this filter will always
+        // return true. This way, if such a reflection frame appears when
+        // it sjould have been filtered by StackWalker, it will make the
+        // test fail.
+        public boolean filter(StackFrame f) {
+            if (filterImplFrames &&
+                f.getClassName().startsWith("jdk.internal.reflect.")) {
+                filtered++;
+                return false;
+            }
+            if (!verbose) System.out.println("    " + f);
+            return true;
+        }
+
+        public String frame(StackFrame f) {
+            return f.getClassName() + "::" + f.getMethodName();
+        }
+
+        List<String> parse(Stream<StackFrame> s) {
+            return s.takeWhile(this::takeWhile)
+                    .filter(this::filter)
+                    .map(this::frame)
+                    .collect(Collectors.toList());
+        }
+
+        /**
+         * The Caller class is used to create instances of
+         * StackInspector, either direcltly, or throug reflection.
+         */
+        public static class Caller {
+            public static StackInspector create(How how) throws Exception {
+                switch(how) {
+                    case NEW: return new StackInspector();
+                    case CONSTRUCTOR: return StackInspector.class
+                        .getConstructor().newInstance();
+                    case CLASS: return StackInspector.class.newInstance();
+                    default: throw new AssertionError(String.valueOf(how));
+                }
+            }
+            public static StackInspector reflect(How how) throws Exception {
+                return (StackInspector) Caller.class.getMethod("create", How.class)
+                      .invoke(null, how);
+            }
+            public static StackInspector handle(How how) throws Exception {
+                Lookup lookup = MethodHandles.lookup();
+                MethodHandle mh = lookup.findStatic(Caller.class, "create",
+                        MethodType.methodType(StackInspector.class, How.class));
+                try {
+                    return (StackInspector) mh.invoke(how);
+                } catch (Error | Exception x) {
+                    throw x;
+                } catch(Throwable t) {
+                    throw new AssertionError(t);
+                }
+            }
+        }
+
+        public static Class<?> getCaller() throws Exception {
+            return walker.get().getCallerClass();
+        }
+
+        public static Class<?> reflectCaller() throws Exception {
+            return (Class<?>)StackWalker.class.getMethod("getCallerClass")
+                .invoke(walker.get());
+        }
+
+        public static Class<?> supplyCaller() throws Exception {
+            return ((Supplier<Class<?>>)StackInspector.walker.get()::getCallerClass).get();
+        }
+
+        public static Class<?> handleCaller() throws Exception {
+            Lookup lookup = MethodHandles.lookup();
+            MethodHandle mh = lookup.findVirtual(StackWalker.class, "getCallerClass",
+                    MethodType.methodType(Class.class));
+            try {
+                return (Class<?>) mh.invoke(walker.get());
+            } catch (Error | Exception x) {
+                throw x;
+            } catch(Throwable t) {
+                throw new AssertionError(t);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/lambda/MetafactoryDescriptorTest.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8035776 8173587
+ * @summary metafactory should fail if instantiatedMethodType does not match sam/bridge descriptors
+ */
+import java.lang.invoke.*;
+import java.util.*;
+
+public class MetafactoryDescriptorTest {
+
+    static final MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+    static MethodType mt(Class<?> ret, Class<?>... params) {
+        return MethodType.methodType(ret, params);
+    }
+
+    public interface I {}
+
+    public static class C {
+        public static void m_void(String arg) {}
+        public static boolean m_boolean(String arg) { return true; }
+        public static char m_char(String arg) { return 'x'; }
+        public static byte m_byte(String arg) { return 12; }
+        public static short m_short(String arg) { return 12; }
+        public static int m_int(String arg) { return 12; }
+        public static long m_long(String arg) { return 12; }
+        public static float m_float(String arg) { return 12; }
+        public static double m_double(String arg) { return 12; }
+        public static String m_String(String arg) { return ""; }
+        public static Integer m_Integer(String arg) { return 23; }
+        public static Object m_Object(String arg) { return new Object(); }
+
+        public static String n_boolean(boolean arg) { return ""; }
+        public static String n_char(char arg) { return ""; }
+        public static String n_byte(byte arg) { return ""; }
+        public static String n_short(short arg) { return ""; }
+        public static String n_int(int arg) { return ""; }
+        public static String n_long(long arg) { return ""; }
+        public static String n_float(float arg) { return ""; }
+        public static String n_double(double arg) { return ""; }
+        public static String n_String(String arg) { return ""; }
+        public static String n_Integer(Integer arg) { return ""; }
+        public static String n_Object(Object arg) { return ""; }
+
+        public static MethodHandle getM(Class<?> c) {
+            try {
+                return lookup.findStatic(C.class, "m_" + c.getSimpleName(), mt(c, String.class));
+            }
+            catch (NoSuchMethodException | IllegalAccessException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public static MethodHandle getN(Class<?> c) {
+            if (c == void.class) return null;
+            try {
+                return lookup.findStatic(C.class, "n_" + c.getSimpleName(), mt(String.class, c));
+            }
+            catch (NoSuchMethodException | IllegalAccessException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+    }
+
+    public static void main(String... args) {
+        Class<?>[] t = { void.class, boolean.class, char.class,
+                         byte.class, short.class, int.class, long.class, float.class, double.class,
+                         String.class, Integer.class, Object.class };
+
+        for (int i = 0; i < t.length; i++) {
+            MethodHandle m = C.getM(t[i]);
+            MethodHandle n = C.getN(t[i]); // null for void.class
+            for (int j = 0; j < t.length; j++) {
+                boolean correctRet = t[j].isAssignableFrom(t[i]) || conversions.contains(t[i], t[j]);
+                test(correctRet, m, mt(t[i], String.class), mt(t[j], String.class));
+                testBridge(correctRet, m, mt(t[i], String.class), mt(t[i], String.class),
+                           mt(t[j], Object.class));
+                testBridge(correctRet, m, mt(t[i], String.class), mt(t[i], String.class),
+                           mt(t[i], CharSequence.class), mt(t[j], Object.class));
+
+                if (t[i] != void.class && t[j] != void.class) {
+                    boolean correctParam = t[j].isAssignableFrom(t[i]);
+                    test(correctParam, n, mt(String.class, t[i]), mt(String.class, t[j]));
+                    testBridge(correctParam, n, mt(String.class, t[i]), mt(String.class, t[i]),
+                            mt(Object.class, t[j]));
+                    testBridge(correctParam, n, mt(String.class, t[i]), mt(String.class, t[i]),
+                            mt(CharSequence.class, t[i]), mt(Object.class, t[j]));
+                }
+
+            }
+        }
+    }
+
+    static void test(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
+        tryMetafactory(correct, mh, instMT, samMT);
+        tryAltMetafactory(correct, mh, instMT, samMT);
+    }
+
+    static void testBridge(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
+        tryAltMetafactory(correct, mh, instMT, samMT, bridgeMTs);
+    }
+
+    static void tryMetafactory(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
+        try {
+            LambdaMetafactory.metafactory(lookup, "run", mt(I.class),
+                                          samMT, mh, instMT);
+            if (!correct) {
+                throw new AssertionError("Unexpected linkage without error:" +
+                                         " impl=" + mh +
+                                         ", inst=" + instMT +
+                                         ", sam=" + samMT);
+            }
+        }
+        catch (LambdaConversionException e) {
+            if (correct) {
+                throw new AssertionError("Unexpected linkage error:" +
+                                         " e=" + e +
+                                         ", impl=" + mh +
+                                         ", inst=" + instMT +
+                                         ", sam=" + samMT);
+            }
+        }
+    }
+
+    static void tryAltMetafactory(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT,
+                                  MethodType... bridgeMTs) {
+        boolean bridge = bridgeMTs.length > 0;
+        Object[] args = new Object[bridge ? 5+bridgeMTs.length : 4];
+        args[0] = samMT;
+        args[1] = mh;
+        args[2] = instMT;
+        args[3] = bridge ? LambdaMetafactory.FLAG_BRIDGES : 0;
+        if (bridge) {
+            args[4] = bridgeMTs.length;
+            for (int i = 0; i < bridgeMTs.length; i++) args[5+i] = bridgeMTs[i];
+        }
+        try {
+            LambdaMetafactory.altMetafactory(lookup, "run", mt(I.class), args);
+            if (!correct) {
+                throw new AssertionError("Unexpected linkage without error:" +
+                                         " impl=" + mh +
+                                         ", inst=" + instMT +
+                                         ", sam=" + samMT +
+                                         ", bridges=" + Arrays.toString(bridgeMTs));
+            }
+        }
+        catch (LambdaConversionException e) {
+            if (correct) {
+                throw new AssertionError("Unexpected linkage error:" +
+                                         " e=" + e +
+                                         ", impl=" + mh +
+                                         ", inst=" + instMT +
+                                         ", sam=" + samMT +
+                                         ", bridges=" + Arrays.toString(bridgeMTs));
+            }
+        }
+    }
+
+    private static class ConversionTable {
+        private final Map<Class<?>, Set<Class<?>>> pairs = new HashMap<>();
+
+        public void put(Class<?> from, Class<?> to) {
+            Set<Class<?>> set = pairs.computeIfAbsent(from, f -> new HashSet<>());
+            set.add(to);
+        }
+
+        public boolean contains(Class<?> from, Class<?> to) {
+            return pairs.containsKey(from) && pairs.get(from).contains(to);
+        }
+    }
+
+    private static ConversionTable conversions = new ConversionTable();
+    static {
+        conversions.put(char.class, int.class);
+        conversions.put(char.class, long.class);
+        conversions.put(char.class, float.class);
+        conversions.put(char.class, double.class);
+        conversions.put(char.class, Character.class);
+        conversions.put(char.class, Object.class);
+        conversions.put(Character.class, char.class);
+        conversions.put(Character.class, int.class);
+        conversions.put(Character.class, long.class);
+        conversions.put(Character.class, float.class);
+        conversions.put(Character.class, double.class);
+
+        conversions.put(byte.class, short.class);
+        conversions.put(byte.class, int.class);
+        conversions.put(byte.class, long.class);
+        conversions.put(byte.class, float.class);
+        conversions.put(byte.class, double.class);
+        conversions.put(byte.class, Byte.class);
+        conversions.put(byte.class, Object.class);
+        conversions.put(Byte.class, byte.class);
+        conversions.put(Byte.class, short.class);
+        conversions.put(Byte.class, int.class);
+        conversions.put(Byte.class, long.class);
+        conversions.put(Byte.class, float.class);
+        conversions.put(Byte.class, double.class);
+
+        conversions.put(short.class, int.class);
+        conversions.put(short.class, long.class);
+        conversions.put(short.class, float.class);
+        conversions.put(short.class, double.class);
+        conversions.put(short.class, Short.class);
+        conversions.put(short.class, Object.class);
+        conversions.put(Short.class, short.class);
+        conversions.put(Short.class, int.class);
+        conversions.put(Short.class, long.class);
+        conversions.put(Short.class, float.class);
+        conversions.put(Short.class, double.class);
+
+        conversions.put(int.class, long.class);
+        conversions.put(int.class, float.class);
+        conversions.put(int.class, double.class);
+        conversions.put(int.class, Integer.class);
+        conversions.put(int.class, Object.class);
+        conversions.put(Integer.class, int.class);
+        conversions.put(Integer.class, long.class);
+        conversions.put(Integer.class, float.class);
+        conversions.put(Integer.class, double.class);
+
+        conversions.put(long.class, float.class);
+        conversions.put(long.class, double.class);
+        conversions.put(long.class, Long.class);
+        conversions.put(long.class, Object.class);
+        conversions.put(Long.class, long.class);
+        conversions.put(Long.class, float.class);
+        conversions.put(Long.class, double.class);
+
+        conversions.put(float.class, double.class);
+        conversions.put(float.class, Float.class);
+        conversions.put(float.class, Object.class);
+        conversions.put(Float.class, float.class);
+        conversions.put(Float.class, double.class);
+
+        conversions.put(double.class, Double.class);
+        conversions.put(double.class, Object.class);
+        conversions.put(Double.class, double.class);
+
+        conversions.put(boolean.class, Boolean.class);
+        conversions.put(boolean.class, Object.class);
+        conversions.put(Boolean.class, boolean.class);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/lambda/MetafactoryMethodNameTest.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8173587
+ * @summary metafactory should fail if the method name is not legal
+ */
+import java.lang.invoke.*;
+import java.util.*;
+
+public class MetafactoryMethodNameTest {
+
+    public static void main(String... args) {
+        goodName("x");
+        goodName("xy");
+
+        goodName("]");
+        goodName("x]");
+        goodName("]y");
+        goodName("x]y");
+
+        goodName("&");
+        goodName("x&");
+        goodName("&y");
+        goodName("x&y");
+
+        badName(".");
+        badName("x.");
+        badName(".y");
+        badName("x.y");
+
+        badName(";");
+        badName("x;");
+        badName(";y");
+        badName("x;y");
+
+        badName("[");
+        badName("x[");
+        badName("[y");
+        badName("x[y");
+
+        badName("/");
+        badName("x/");
+        badName("/y");
+        badName("x/y");
+
+        badName("<");
+        badName("x<");
+        badName("<y");
+        badName("x<y");
+
+        badName(">");
+        badName("x>");
+        badName(">y");
+        badName("x>y");
+
+        badName("");
+        badName("<init>");
+        badName("<clinit>");
+    }
+
+    static MethodType mt(Class<?> ret, Class<?>... params) {
+        return MethodType.methodType(ret, params);
+    }
+
+    static MethodHandle smh(Class<?> c, String name, MethodType desc) {
+        try {
+            return MethodHandles.lookup().findStatic(c, name, desc);
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static Object[] arr(Object... args) {
+        return args;
+    }
+
+    public static class C {
+        public static void m() {}
+    }
+
+    public interface I {}
+
+    private static MethodHandles.Lookup lookup = MethodHandles.lookup();
+    private static MethodType toI = mt(I.class);
+    private static MethodType toVoid = mt(void.class);
+    private static MethodHandle mh = smh(C.class, "m", toVoid);
+    private static Class<?> lce = LambdaConversionException.class;
+
+    static void goodName(String name) {
+        succeedMFLinkage(lookup, name, toI, toVoid, mh, toVoid);
+        succeedAltMFLinkage(lookup, name, toI, arr(toVoid, mh, toVoid, LambdaMetafactory.FLAG_SERIALIZABLE));
+    }
+
+    static void badName(String name) {
+        failMFLinkage(lookup, name, toI, toVoid, mh, toVoid, lce);
+        failAltMFLinkage(lookup, name, toI, arr(toVoid, mh, toVoid, LambdaMetafactory.FLAG_SERIALIZABLE), lce);
+    }
+
+    static CallSite succeedMFLinkage(MethodHandles.Lookup lookup,
+                                    String name,
+                                    MethodType capType,
+                                    MethodType desc,
+                                    MethodHandle impl,
+                                    MethodType checked) {
+        try {
+            return LambdaMetafactory.metafactory(lookup, name, capType, desc, impl, checked);
+        } catch (Throwable t) {
+            String msg = String.format("Unexpected exception during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
+                    lookup, name, capType, desc, impl, checked);
+            throw new AssertionError(msg, t);
+        }
+    }
+
+    static void failMFLinkage(MethodHandles.Lookup lookup,
+                              String name,
+                              MethodType capType,
+                              MethodType desc,
+                              MethodHandle impl,
+                              MethodType checked,
+                              Class<?> expectedExceptionType) {
+        try {
+            LambdaMetafactory.metafactory(lookup, name, capType, desc, impl, checked);
+        } catch (Throwable t) {
+            if (expectedExceptionType.isInstance(t)) {
+                return;
+            } else {
+                String msg = String.format("Unexpected exception: expected %s during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
+                        expectedExceptionType.getName(),
+                        lookup, name, capType, desc, impl, checked);
+                throw new AssertionError(msg, t);
+            }
+        }
+        String msg = String.format("Unexpected success: expected %s during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
+                expectedExceptionType.getName(),
+                lookup, name, capType, desc, impl, checked);
+        throw new AssertionError(msg);
+    }
+
+    static CallSite succeedAltMFLinkage(MethodHandles.Lookup lookup,
+                                        String name,
+                                        MethodType capType,
+                                        Object[] args) {
+        try {
+            return LambdaMetafactory.altMetafactory(lookup, name, capType, args);
+        } catch (Throwable t) {
+            String msg = String.format("Unexpected exception during linkage for metafactory(%s, %s, %s, %s)",
+                    lookup, name, capType, Arrays.asList(args));
+            throw new AssertionError(msg, t);
+        }
+    }
+
+    static void failAltMFLinkage(MethodHandles.Lookup lookup,
+                                 String name,
+                                 MethodType capType,
+                                 Object[] args,
+                                 Class<?> expectedExceptionType) {
+        try {
+            LambdaMetafactory.altMetafactory(lookup, name, capType, args);
+        } catch (Throwable t) {
+            if (expectedExceptionType.isInstance(t)) {
+                return;
+            } else {
+                String msg = String.format("Unexpected exception: expected %s during linkage for metafactory(%s, %s, %s, %s)",
+                        expectedExceptionType.getName(),
+                        lookup, name, capType, Arrays.asList(args));
+                throw new AssertionError(msg, t);
+            }
+        }
+        String msg = String.format("Unexpected success: expected %s during linkage for metafactory(%s, %s, %s, %s)",
+                expectedExceptionType.getName(),
+                lookup, name, capType, Arrays.asList(args));
+        throw new AssertionError(msg);
+    }
+
+}
--- a/test/java/lang/invoke/lambda/MetafactorySamReturnTest.java	Thu Feb 09 17:21:47 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2014, 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 8035776
- * @summary metafactory should fail if impl return does not match sam/bridge returns
- */
-import java.lang.invoke.*;
-import java.util.Arrays;
-import static java.lang.invoke.MethodType.methodType;
-
-public class MetafactorySamReturnTest {
-
-    static final MethodHandles.Lookup lookup = MethodHandles.lookup();
-
-    public interface I {}
-
-    public static class C {
-        public static void m_void(String arg) {}
-        public static boolean m_boolean(String arg) { return true; }
-        public static char m_char(String arg) { return 'x'; }
-        public static byte m_byte(String arg) { return 12; }
-        public static short m_short(String arg) { return 12; }
-        public static int m_int(String arg) { return 12; }
-        public static long m_long(String arg) { return 12; }
-        public static float m_float(String arg) { return 12; }
-        public static double m_double(String arg) { return 12; }
-        public static String m_String(String arg) { return ""; }
-        public static Integer m_Integer(String arg) { return 23; }
-        public static Object m_Object(String arg) { return new Object(); }
-
-        public static MethodHandle getMH(Class<?> c) {
-            try {
-                return lookup.findStatic(C.class, "m_" + c.getSimpleName(), methodType(c, String.class));
-            }
-            catch (NoSuchMethodException | IllegalAccessException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    public static void main(String... args) {
-        Class<?>[] t = { void.class, boolean.class, char.class,
-                         byte.class, short.class, int.class, long.class, float.class, double.class,
-                         String.class, Integer.class, Object.class };
-
-        for (int i = 0; i < t.length; i++) {
-            MethodHandle mh = C.getMH(t[i]);
-            for (int j = 0; j < t.length; j++) {
-                // TEMPORARY EXCEPTIONS
-                if (t[j] == void.class) continue;
-                if (t[i].isPrimitive() && t[j] == Object.class) continue;
-                if (t[i] == char.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == byte.class && (t[j] == short.class || t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == short.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == int.class && (t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == long.class && (t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == float.class && t[j] == double.class) continue;
-                if (t[i] == int.class && t[j] == Integer.class) continue;
-                if (t[i] == Integer.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                // END TEMPORARY EXCEPTIONS
-                boolean correct = (t[i].isPrimitive() || t[j].isPrimitive())
-                                  ? t[i] == t[j]
-                                  : t[j].isAssignableFrom(t[i]);
-                MethodType mti = methodType(t[i], String.class);
-                MethodType mtiCS = methodType(t[i], CharSequence.class);
-                MethodType mtj = methodType(t[j], String.class);
-                MethodType mtjObj = methodType(t[j], Object.class);
-                test(correct, mh, mti, mtj);
-                testBridge(correct, mh, mti, mti, mtjObj);
-                testBridge(correct, mh, mti, mti, mtiCS, mtjObj);
-            }
-        }
-    }
-
-    static void test(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
-        tryMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
-        tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
-    }
-
-    static void testBridge(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
-        tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT, bridgeMTs);
-    }
-
-    static void tryMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
-                               MethodType instMT, MethodType samMT) {
-        try {
-            LambdaMetafactory.metafactory(lookup, "run", methodType(I.class, captured),
-                                          samMT, mh, instMT);
-            if (!correct) {
-                throw new AssertionError("Uncaught linkage error:" +
-                                         " impl=" + mh +
-                                         ", captured=" + Arrays.toString(captured) +
-                                         ", inst=" + instMT +
-                                         ", sam=" + samMT);
-            }
-        }
-        catch (LambdaConversionException e) {
-            if (correct) {
-                throw new AssertionError("Unexpected linkage error:" +
-                                         " e=" + e +
-                                         ", impl=" + mh +
-                                         ", captured=" + Arrays.toString(captured) +
-                                         ", inst=" + instMT +
-                                         ", sam=" + samMT);
-            }
-        }
-    }
-
-    static void tryAltMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
-                                  MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
-        boolean bridge = bridgeMTs.length > 0;
-        Object[] args = new Object[bridge ? 5+bridgeMTs.length : 4];
-        args[0] = samMT;
-        args[1] = mh;
-        args[2] = instMT;
-        args[3] = bridge ? LambdaMetafactory.FLAG_BRIDGES : 0;
-        if (bridge) {
-            args[4] = bridgeMTs.length;
-            for (int i = 0; i < bridgeMTs.length; i++) args[5+i] = bridgeMTs[i];
-        }
-        try {
-            LambdaMetafactory.altMetafactory(lookup, "run", methodType(I.class, captured), args);
-            if (!correct) {
-                throw new AssertionError("Uncaught linkage error:" +
-                                         " impl=" + mh +
-                                         ", captured=" + Arrays.toString(captured) +
-                                         ", inst=" + instMT +
-                                         ", sam=" + samMT +
-                                         ", bridges=" + Arrays.toString(bridgeMTs));
-            }
-        }
-        catch (LambdaConversionException e) {
-            if (correct) {
-                throw new AssertionError("Unexpected linkage error:" +
-                                         " e=" + e +
-                                         ", impl=" + mh +
-                                         ", captured=" + Arrays.toString(captured) +
-                                         ", inst=" + instMT +
-                                         ", sam=" + samMT +
-                                         ", bridges=" + Arrays.toString(bridgeMTs));
-            }
-        }
-    }
-
-}
--- a/test/java/nio/channels/Selector/SelectTimeout.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/java/nio/channels/Selector/SelectTimeout.java	Thu Feb 09 18:10:19 2017 +0000
@@ -30,14 +30,13 @@
  */
 import java.io.IOException;
 import java.nio.channels.Selector;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 
 public class SelectTimeout {
     private static final long BIG_TIMEOUT    = 100_000_001_000L; // 8165000
     private static final long BIGGER_TIMEOUT = 850_000_000_000_000L; // 8172547
-    private static final long SLEEP_MILLIS   = 10000;
-
-    private static volatile Exception theException;
-    private static volatile boolean isTimedOut;
+    private static final long SLEEP_MILLIS   = 10_000;
 
     public static void main(String[] args)
         throws IOException, InterruptedException {
@@ -59,17 +58,18 @@
 
     private static boolean test(final long timeout)
         throws InterruptedException, IOException {
-        theException = null;
+        AtomicReference<Exception> theException =
+            new AtomicReference<>();
+        AtomicBoolean isTimedOut = new AtomicBoolean();
 
         Selector selector = Selector.open();
 
         Thread t = new Thread(() -> {
             try {
-                isTimedOut = false;
                 selector.select(timeout);
-                isTimedOut = true;
+                isTimedOut.set(true);
             } catch (IOException ioe) {
-                theException = ioe;
+                theException.set(ioe);
             }
         });
         t.start();
@@ -77,8 +77,8 @@
         t.join(SLEEP_MILLIS);
 
         boolean result;
-        if (theException == null) {
-            if (timeout > SLEEP_MILLIS && isTimedOut) {
+        if (theException.get() == null) {
+            if (timeout > SLEEP_MILLIS && isTimedOut.get()) {
                 System.err.printf("Test timed out early with timeout %d%n",
                     timeout);
                 result = false;
@@ -88,11 +88,12 @@
             }
         } else {
             System.err.printf("Test failed with timeout %d%n", timeout);
-            theException.printStackTrace();
+            theException.get().printStackTrace();
             result = false;
         }
 
         t.interrupt();
+        selector.close();
 
         return result;
     }
--- a/test/java/nio/file/FileSystem/Basic.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/java/nio/file/FileSystem/Basic.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,11 +30,18 @@
  */
 
 import java.io.File;
-import java.nio.file.*;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.ProviderNotFoundException;
 import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
 import jdk.testlibrary.FileUtils;
 
 /**
@@ -47,6 +54,44 @@
             throw new RuntimeException(msg);
     }
 
+    static void checkFileStores(String os, FileSystem fs) throws IOException {
+        boolean checkFileStores = true;
+        if (!os.equals("Windows")) {
+            // try to check whether 'df' hangs
+            System.out.println("\n--- Begin df output ---");
+            System.out.flush();
+            Process proc = new ProcessBuilder("df").inheritIO().start();
+            try {
+                proc.waitFor(90, TimeUnit.SECONDS);
+            } catch (InterruptedException ignored) {
+            }
+            System.out.println("--- End df output ---\n");
+            System.out.flush();
+            try {
+                int exitValue = proc.exitValue();
+                if (exitValue != 0) {
+                    System.err.printf("df process exited with %d != 0%n",
+                        exitValue);
+                    checkFileStores = false;
+                }
+            } catch (IllegalThreadStateException ignored) {
+                System.err.println("df command apparently hung");
+                checkFileStores = false;
+            }
+        }
+
+        // sanity check method
+        if (checkFileStores) {
+            System.out.println("\n--- Begin FileStores ---");
+            for (FileStore store: fs.getFileStores()) {
+                System.out.println(store);
+            }
+            System.out.println("--- EndFileStores ---\n");
+        } else {
+            System.err.println("Skipping FileStore check due to df failure");
+        }
+    }
+
     static void checkSupported(FileSystem fs, String... views) {
         for (String view: views) {
             check(fs.supportedFileAttributeViews().contains(view),
@@ -70,7 +115,9 @@
         }
     }
 
-    public static void main(String[] args) throws IOException, URISyntaxException {
+    public static void main(String[] args)
+        throws IOException, URISyntaxException {
+        String os = System.getProperty("os.name");
         FileSystem fs = FileSystems.getDefault();
 
         // close should throw UOE
@@ -85,15 +132,11 @@
         check(fs.provider().getScheme().equals("file"),
             "should use 'file' scheme");
 
-        // santity check method - need to re-visit this in future as I/O errors
-        // are possible
-        for (FileStore store: fs.getFileStores()) {
-            System.out.println(store);
-        }
+        // sanity check FileStores
+        checkFileStores(os, fs);
 
         // sanity check supportedFileAttributeViews
         checkSupported(fs, "basic");
-        String os = System.getProperty("os.name");
         if (os.equals("SunOS"))
             checkSupported(fs, "posix", "unix", "owner", "acl", "user");
         if (os.equals("Linux"))
--- a/test/java/time/TEST.properties	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/java/time/TEST.properties	Thu Feb 09 18:10:19 2017 +0000
@@ -1,6 +1,5 @@
-# Threeten test uses TestNG
+# java.time tests use TestNG
 TestNG.dirs = .
 othervm.dirs = tck/java/time/chrono test/java/time/chrono test/java/time/format
 lib.dirs = ../../lib/testlibrary
 lib.build = jdk.testlibrary.RandomFactory
-modules = java.base/java.time:open java.base/java.time.chrono:open java.base/java.time.zone:open
--- a/test/java/time/tck/java/time/AbstractTCKTest.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/java/time/tck/java/time/AbstractTCKTest.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,14 +69,35 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamConstants;
 import java.io.Serializable;
-import java.lang.reflect.Field;
 import java.util.Formatter;
+import java.util.Map;
 
 /**
  * Base test class.
  */
 public abstract class AbstractTCKTest {
 
+    /**
+     * Map from package name to the serialVersionUID of the .Ser class for the package.
+     */
+    private static Map<String, Long> serialVersionUIDs = Map.of(
+                "java.time",        -7683839454370182990L,
+                "java.time.chrono", -6103370247208168577L,
+                "java.time.zone",   -8885321777449118786L
+                );
+
+    /**
+     * Returns the serialVersionUID for the class.
+     * The SUIDs are defined by the specification for each class.
+     * @param serClass the class to return the SUID of
+     * @return returns the serialVersionUID for the class
+     */
+    public final static long getSUID(Class<?> serClass) {
+        String pkgName = serClass.getPackageName();
+        return serialVersionUIDs.get(pkgName);
+    }
+
+
     protected static boolean isIsoLeap(long year) {
         if (year % 4 != 0) {
             return false;
@@ -111,10 +132,8 @@
 
     protected static void assertSerializedBySer(Object object, byte[] expectedBytes, byte[]... matches) throws Exception {
         String serClass = object.getClass().getPackage().getName() + ".Ser";
-        Class<?> serCls = Class.forName(serClass);
-        Field field = serCls.getDeclaredField("serialVersionUID");
-        field.setAccessible(true);
-        long serVer = (Long) field.get(null);
+        long serVer = getSUID(object.getClass());
+
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) {
             oos.writeObject(object);
@@ -172,9 +191,8 @@
      * @throws Exception if an unexpected condition occurs
      */
     protected static void assertNotSerializable(Class<?> serClass) throws Exception {
-        Field field = serClass.getDeclaredField("serialVersionUID");
-        field.setAccessible(true);
-        long serVer = (Long) field.get(null);
+        long serVer = getSUID(serClass);
+
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (DataOutputStream out = new DataOutputStream(baos)) {
             out.writeShort(ObjectStreamConstants.STREAM_MAGIC);
@@ -201,7 +219,6 @@
         fail("Class should not be deserializable " + serClass.getName());
     }
 
-
     /**
      * Utility method to dump a byte array in a java syntax.
      * @param bytes and array of bytes
--- a/test/java/time/tck/java/time/TCKOffsetDateTime.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/java/time/tck/java/time/TCKOffsetDateTime.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,8 +104,6 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Duration;
@@ -470,24 +468,12 @@
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=NullPointerException.class)
     public void constructor_nullTime() throws Throwable  {
-        Constructor<OffsetDateTime> con = OffsetDateTime.class.getDeclaredConstructor(LocalDateTime.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(null, OFFSET_PONE);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
+        OffsetDateTime.of(null, OFFSET_PONE);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void constructor_nullOffset() throws Throwable  {
-        Constructor<OffsetDateTime> con = OffsetDateTime.class.getDeclaredConstructor(LocalDateTime.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(LocalDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30)), null);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
+        OffsetDateTime.of(LocalDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30)), null);
     }
 
     //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/TCKOffsetTime.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/java/time/tck/java/time/TCKOffsetTime.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -89,8 +89,6 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Instant;
@@ -465,28 +463,16 @@
     }
 
     //-----------------------------------------------------------------------
-    // constructor
+    // constructor via factory
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=NullPointerException.class)
     public void constructor_nullTime() throws Throwable  {
-        Constructor<OffsetTime> con = OffsetTime.class.getDeclaredConstructor(LocalTime.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(null, OFFSET_PONE);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
+        OffsetTime.of(null, OFFSET_PONE);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void constructor_nullOffset() throws Throwable  {
-        Constructor<OffsetTime> con = OffsetTime.class.getDeclaredConstructor(LocalTime.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(LocalTime.of(11, 30, 0, 0), null);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
+       OffsetTime.of(LocalTime.of(11, 30, 0, 0), null);
     }
 
     //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java	Thu Feb 09 18:10:19 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -63,8 +63,11 @@
 import org.testng.annotations.Test;
 import tck.java.time.AbstractTCKTest;
 
-import java.io.*;
-import java.lang.reflect.Field;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamConstants;
 import java.time.DateTimeException;
 import java.time.ZoneId;
 import java.time.zone.ZoneRulesException;
@@ -153,10 +156,8 @@
 
     private ZoneId deserialize(String id) throws Exception {
         String serClass = ZoneId.class.getPackage().getName() + ".Ser";
-        Class<?> serCls = Class.forName(serClass);
-        Field field = serCls.getDeclaredField("serialVersionUID");
-        field.setAccessible(true);
-        long serVer = (Long) field.get(null);
+        long serVer = getSUID(ZoneId.class);
+
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (DataOutputStream dos = new DataOutputStream(baos)) {
             dos.writeShort(ObjectStreamConstants.STREAM_MAGIC);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/test/java/time/TEST.properties	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,2 @@
+# java.time test system clock
+modules = java.base/java.time:open
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/org/omg/CORBA/OrbPropertiesTest.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import org.omg.CORBA.ORB;
+
+/*
+ * @test
+ * @bug 8049375
+ * @summary Extend how the org.omg.CORBA.ORB handles the search for orb.properties
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @modules java.corba
+ * @compile OrbPropertiesTest.java TestOrbImpl.java TestSingletonOrbImpl.java
+ * @run main/othervm
+ *    -Djava.naming.provider.url=iiop://localhost:1050
+ *    -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ *    OrbPropertiesTest -port 1049
+ * @run main/othervm/secure=java.lang.SecurityManager/policy=jtreg.test.policy
+ *    -Djava.naming.provider.url=iiop://localhost:3050
+ *    -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ *    OrbPropertiesTest -port 3049
+ */
+public class OrbPropertiesTest {
+
+    public static void main(String[] args) throws Exception {
+        updateOrbPropertiesFile();
+        // create and initialize the ORB
+        ORB orb = ORB.init(args, null);
+        if (!(orb instanceof TestOrbImpl)) {
+            throw new RuntimeException("org.omg.CORBA.ORBClass property not set as expected");
+        }
+        ORB singletonOrb = ORB.init();
+        System.out.println("singletonOrb class == " + singletonOrb.getClass().getName());
+        if (!(singletonOrb instanceof TestSingletonOrbImpl)) {
+            throw new RuntimeException("org.omg.CORBA.ORBSingletonClass property not set as expected");
+        }
+
+    }
+
+    private static void updateOrbPropertiesFile() throws Exception {
+        String orbPropertiesFile = System.getProperty("java.home", ".") + "/conf/orb.properties";
+        String orbClassMapping = "org.omg.CORBA.ORBClass TestOrbImpl";
+        String orbSingletonClassMapping = "org.omg.CORBA.ORBSingletonClass TestSingletonOrbImpl";
+        String orbPropertiesMappings = orbClassMapping + "\n" + orbSingletonClassMapping +"\n";
+        try (PrintWriter hfPWriter = new PrintWriter(new BufferedWriter(
+                new FileWriter(orbPropertiesFile, false)))) {
+            hfPWriter.println(orbPropertiesMappings);
+        } catch (IOException ioEx) {
+            ioEx.printStackTrace();
+            throw ioEx;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/org/omg/CORBA/TestOrbImpl.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.applet.Applet;
+import java.util.Properties;
+
+import org.omg.CORBA.Any;
+import org.omg.CORBA.Context;
+import org.omg.CORBA.ContextList;
+import org.omg.CORBA.Environment;
+import org.omg.CORBA.ExceptionList;
+import org.omg.CORBA.NVList;
+import org.omg.CORBA.NamedValue;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.Object;
+import org.omg.CORBA.Request;
+import org.omg.CORBA.StructMember;
+import org.omg.CORBA.TCKind;
+import org.omg.CORBA.TypeCode;
+import org.omg.CORBA.UnionMember;
+import org.omg.CORBA.WrongTransaction;
+import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CORBA.portable.OutputStream;
+
+
+public class TestOrbImpl extends ORB{
+
+    @Override
+    protected void set_parameters(String[] args, Properties props) {
+
+    }
+
+    @Override
+    protected void set_parameters(Applet app, Properties props) {
+
+    }
+
+    @Override
+    public String[] list_initial_services() {
+        return null;
+    }
+
+    @Override
+    public Object resolve_initial_references(String object_name)
+            throws InvalidName {
+        return null;
+    }
+
+    @Override
+    public String object_to_string(Object obj) {
+        return null;
+    }
+
+    @Override
+    public Object string_to_object(String str) {
+        return null;
+    }
+
+    @Override
+    public NVList create_list(int count) {
+        return null;
+    }
+
+    @Override
+    public NamedValue create_named_value(String s, Any any, int flags) {
+        return null;
+    }
+
+    @Override
+    public ExceptionList create_exception_list() {
+        return null;
+    }
+
+    @Override
+    public ContextList create_context_list() {
+        return null;
+    }
+
+    @Override
+    public Context get_default_context() {
+        return null;
+    }
+
+    @Override
+    public Environment create_environment() {
+        return null;
+    }
+
+    @Override
+    public OutputStream create_output_stream() {
+        return null;
+    }
+
+    @Override
+    public void send_multiple_requests_oneway(Request[] req) {
+
+    }
+
+    @Override
+    public void send_multiple_requests_deferred(Request[] req) {
+
+    }
+
+    @Override
+    public boolean poll_next_response() {
+        return false;
+    }
+
+    @Override
+    public Request get_next_response() throws WrongTransaction {
+        return null;
+    }
+
+    @Override
+    public TypeCode get_primitive_tc(TCKind tcKind) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_struct_tc(String id, String name,
+            StructMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_union_tc(String id, String name,
+            TypeCode discriminator_type, UnionMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_enum_tc(String id, String name, String[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_alias_tc(String id, String name,
+            TypeCode original_type) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_exception_tc(String id, String name,
+            StructMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_interface_tc(String id, String name) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_string_tc(int bound) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_wstring_tc(int bound) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_sequence_tc(int bound, TypeCode element_type) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_recursive_sequence_tc(int bound, int offset) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_array_tc(int length, TypeCode element_type) {
+        return null;
+    }
+
+    @Override
+    public Any create_any() {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/org/omg/CORBA/TestSingletonOrbImpl.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.applet.Applet;
+import java.util.Properties;
+
+import org.omg.CORBA.Any;
+import org.omg.CORBA.Context;
+import org.omg.CORBA.ContextList;
+import org.omg.CORBA.Environment;
+import org.omg.CORBA.ExceptionList;
+import org.omg.CORBA.NVList;
+import org.omg.CORBA.NamedValue;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.Object;
+import org.omg.CORBA.Request;
+import org.omg.CORBA.StructMember;
+import org.omg.CORBA.TCKind;
+import org.omg.CORBA.TypeCode;
+import org.omg.CORBA.UnionMember;
+import org.omg.CORBA.WrongTransaction;
+import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CORBA.portable.OutputStream;
+
+
+public class TestSingletonOrbImpl extends ORB {
+
+    @Override
+    protected void set_parameters(String[] args, Properties props) {
+
+    }
+
+    @Override
+    protected void set_parameters(Applet app, Properties props) {
+
+    }
+
+    @Override
+    public String[] list_initial_services() {
+        return null;
+    }
+
+    @Override
+    public Object resolve_initial_references(String object_name)
+            throws InvalidName {
+        return null;
+    }
+
+    @Override
+    public String object_to_string(Object obj) {
+        return null;
+    }
+
+    @Override
+    public Object string_to_object(String str) {
+        return null;
+    }
+
+    @Override
+    public NVList create_list(int count) {
+        return null;
+    }
+
+    @Override
+    public NamedValue create_named_value(String s, Any any, int flags) {
+        return null;
+    }
+
+    @Override
+    public ExceptionList create_exception_list() {
+        return null;
+    }
+
+    @Override
+    public ContextList create_context_list() {
+        return null;
+    }
+
+    @Override
+    public Context get_default_context() {
+        return null;
+    }
+
+    @Override
+    public Environment create_environment() {
+        return null;
+    }
+
+    @Override
+    public OutputStream create_output_stream() {
+        return null;
+    }
+
+    @Override
+    public void send_multiple_requests_oneway(Request[] req) {
+
+    }
+
+    @Override
+    public void send_multiple_requests_deferred(Request[] req) {
+
+    }
+
+    @Override
+    public boolean poll_next_response() {
+        return false;
+    }
+
+    @Override
+    public Request get_next_response() throws WrongTransaction {
+        return null;
+    }
+
+    @Override
+    public TypeCode get_primitive_tc(TCKind tcKind) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_struct_tc(String id, String name,
+            StructMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_union_tc(String id, String name,
+            TypeCode discriminator_type, UnionMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_enum_tc(String id, String name, String[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_alias_tc(String id, String name,
+            TypeCode original_type) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_exception_tc(String id, String name,
+            StructMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_interface_tc(String id, String name) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_string_tc(int bound) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_wstring_tc(int bound) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_sequence_tc(int bound, TypeCode element_type) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_recursive_sequence_tc(int bound, int offset) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_array_tc(int length, TypeCode element_type) {
+        return null;
+    }
+
+    @Override
+    public Any create_any() {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/org/omg/CORBA/jtreg.test.policy	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+grant {
+  permission java.util.PropertyPermission "*", "read";
+  permission java.io.FilePermission "<<ALL FILES>>", "read, write, execute";
+};
+
+grant codeBase "file:${test.classes}/*" {
+  permission java.net.SocketPermission "*:*", "connect, accept, listen, resolve";
+  permission java.lang.RuntimePermission "accessClassInPackage.com.sun.jndi.cosnaming";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java	Thu Feb 09 18:10:19 2017 +0000
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8173783
+ * @summary 6u141 IllegalArgumentException: jdk.tls.namedGroups
+ * run main/othervm HelloExtensionsTest
+ * run main/othervm HelloExtensionsTest -Djdk.tls.namedGroups="bug, bug"
+ * run main/othervm HelloExtensionsTest -Djdk.tls.namedGroups="secp521r1"
+ *
+ */
+import javax.crypto.*;
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.nio.*;
+import java.security.*;
+
+public class HelloExtensionsTest {
+
+    private static boolean debug = false;
+    private static boolean proceed = true;
+    private static boolean EcAvailable = isEcAvailable();
+
+    static String pathToStores = "../../../../javax/net/ssl/etc";
+    private static String keyStoreFile = "keystore";
+    private static String trustStoreFile = "truststore";
+    private static String passwd = "passphrase";
+
+    private static String keyFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + keyStoreFile;
+    private static String trustFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+    private static void checkDone(SSLEngine ssle) throws Exception {
+        if (!ssle.isInboundDone()) {
+            throw new Exception("isInboundDone isn't done");
+        }
+        if (!ssle.isOutboundDone()) {
+            throw new Exception("isOutboundDone isn't done");
+        }
+    }
+
+    private static void runTest(SSLEngine ssle) throws Exception {
+
+         /*
+
+         A client hello message captured via wireshark by selecting
+         a TLSv1.2 Client Hello record and clicking through to the
+         TLSv1.2 Record Layer line and then selecting the hex stream
+         via "copy -> bytes -> hex stream".
+
+         For Record purposes, here's the ClientHello :
+
+         *** ClientHello, TLSv1.2
+         RandomCookie:  GMT: 1469560450 bytes = { 108, 140, 12, 202,
+         2, 213, 10, 236, 143, 223, 58, 162, 228, 155, 239, 3, 98,
+         232, 89, 41, 116, 120, 13, 37, 105, 153, 97, 241 }
+         Session ID:  {}
+         Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+         TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256,
+         TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
+         TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
+         TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+         TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+         TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+         TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+         TLS_RSA_WITH_AES_128_CBC_SHA,
+         TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+         TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+         TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+         TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+         TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+         TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+         TLS_RSA_WITH_AES_128_GCM_SHA256,
+         TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+         TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+         TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+         TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
+         TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+         SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+         TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+         TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+         SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+         SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+         TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
+         Compression Methods:  { 0 }
+         Extension elliptic_curves, curve names: {secp256r1,
+         sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1,
+         sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1,
+         sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1,
+         secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
+         Extension ec_point_formats, formats: [uncompressed]
+         Extension signature_algorithms, signature_algorithms:
+         SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA,
+         SHA256withECDSA, SHA256withRSA, Unknown (hash:0x3, signature:0x3),
+         Unknown (hash:0x3, signature:0x1), SHA1withECDSA,
+         SHA1withRSA, SHA1withDSA
+         Extension server_name, server_name:
+         [host_name: bugs.openjdk.java.net]
+         */
+
+        String hello = "16030300df010000db03035898b7826c8c0cc" +
+            "a02d50aec8fdf3aa2e49bef0362e8592974780d25699961f" +
+            "100003ac023c027003cc025c02900670040c009c013002fc" +
+            "004c00e00330032c02bc02f009cc02dc031009e00a2c008c" +
+            "012000ac003c00d0016001300ff01000078000a003400320" +
+            "0170001000300130015000600070009000a0018000b000c0" +
+            "019000d000e000f001000110002001200040005001400080" +
+            "016000b00020100000d00180016060306010503050104030" +
+            "401030303010203020102020000001a00180000156275677" +
+            "32e6f70656e6a646b2e6a6176612e6e6574";
+
+        byte[] msg_clihello = hexStringToByteArray(hello);
+        ByteBuffer bf_clihello = ByteBuffer.wrap(msg_clihello);
+
+        SSLSession session = ssle.getSession();
+        int appBufferMax = session.getApplicationBufferSize();
+        int netBufferMax = session.getPacketBufferSize();
+
+        ByteBuffer serverIn = ByteBuffer.allocate(appBufferMax + 50);
+        ByteBuffer serverOut = ByteBuffer.wrap("I'm Server".getBytes());
+        ByteBuffer sTOc = ByteBuffer.allocate(netBufferMax);
+
+        ssle.beginHandshake();
+
+        // unwrap the clientHello message.
+        SSLEngineResult result = ssle.unwrap(bf_clihello, serverIn);
+        System.out.println("server unwrap " + result);
+        runDelegatedTasks(result, ssle);
+
+        if (!proceed) {
+            //expected exception occurred. Don't process anymore
+            return;
+        }
+
+        // one more step, ensure the clientHello message is parsed.
+        SSLEngineResult.HandshakeStatus status = ssle.getHandshakeStatus();
+        if ( status == HandshakeStatus.NEED_UNWRAP) {
+            result = ssle.unwrap(bf_clihello, serverIn);
+            System.out.println("server unwrap " + result);
+            runDelegatedTasks(result, ssle);
+        } else if ( status == HandshakeStatus.NEED_WRAP) {
+            result = ssle.wrap(serverOut, sTOc);
+            System.out.println("server wrap " + result);
+            runDelegatedTasks(result, ssle);
+        } else {
+            throw new Exception("unexpected handshake status " + status);
+        }
+
+        // enough, stop
+    }
+
+    /*
+     * If the result indicates that we have outstanding tasks to do,
+     * go ahead and run them in this thread.
+     */
+    private static void runDelegatedTasks(SSLEngineResult result,
+            SSLEngine engine) throws Exception {
+
+        if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+            Runnable runnable;
+            try {
+                while ((runnable = engine.getDelegatedTask()) != null) {
+                    log("\trunning delegated task...");
+                    runnable.run();
+                }
+            } catch (ExceptionInInitializerError e) {
+                String v = System.getProperty("jdk.tls.namedGroups");
+                if (!EcAvailable || v == null) {
+                    // we weren't expecting this if no EC providers
+                    throw new RuntimeException("Unexpected Error :" + e);
+                }
+                if (v != null && v.contains("bug")) {
+                    // OK - we were expecting this Error
+                    log("got expected error for bad jdk.tls.namedGroups");
+                    proceed = false;
+                    return;
+                } else {
+                    System.out.println("Unexpected error. " +
+                        "jdk.tls.namedGroups value: " + v);
+                    throw e;
+                }
+            }
+            HandshakeStatus hsStatus = engine.getHandshakeStatus();
+            if (hsStatus == HandshakeStatus.NEED_TASK) {
+                throw new Exception(
+                    "handshake shouldn't need additional tasks");
+            }
+            log("\tnew HandshakeStatus: " + hsStatus);
+        }
+    }
+
+    private static byte[] hexStringToByteArray(String s) {
+        int len = s.length();
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+                + Character.digit(s.charAt(i+1), 16));
+        }
+        return data;
+    }
+
+    private static boolean isEcAvailable() {
+        try {
+            Signature.getInstance("SHA1withECDSA");
+            Signature.getInstance("NONEwithECDSA");
+            KeyAgreement.getInstance("ECDH");
+            KeyFactory.getInstance("EC");
+            KeyPairGenerator.getInstance("EC");
+            AlgorithmParameters.getInstance("EC");
+        } catch (Exception e) {
+            log("EC not available. Received: " + e);
+            return false;
+        }
+        return true;
+    }
+
+    public static void main(String args[]) throws Exception {
+        SSLEngine ssle = createSSLEngine(keyFilename, trustFilename);
+        runTest(ssle);
+        System.out.println("Test Passed.");
+    }
+
+    /*
+     * Create an initialized SSLContext to use for this test.
+     */
+    static private SSLEngine createSSLEngine(String keyFile, String trustFile)
+            throws Exception {
+
+        SSLEngine ssle;
+
+        KeyStore ks = KeyStore.getInstance("JKS");
+        KeyStore ts = KeyStore.getInstance("JKS");
+
+        char[] passphrase = "passphrase".toCharArray();
+
+        ks.load(new FileInputStream(keyFile), passphrase);
+        ts.load(new FileInputStream(trustFile), passphrase);
+
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+        kmf.init(ks, passphrase);
+
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+        tmf.init(ts);
+
+        SSLContext sslCtx = SSLContext.getInstance("TLS");
+
+        sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+        ssle = sslCtx.createSSLEngine();
+        ssle.setUseClientMode(false);
+
+        return ssle;
+    }
+
+
+    private static void log(String str) {
+        if (debug) {
+            System.out.println(str);
+        }
+    }
+}
--- a/test/sun/security/tools/jarsigner/TimestampCheck.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/sun/security/tools/jarsigner/TimestampCheck.java	Thu Feb 09 18:10:19 2017 +0000
@@ -456,7 +456,7 @@
                 .shouldMatch("Timestamp signature algorithm: .*key.*weak");
         verify(file, "-J-Djava.security.debug=jar")
                 .shouldHaveExitValue(0)
-                .shouldMatch("SignatureException:.*Disabled");
+                .shouldMatch("SignatureException:.*disabled");
     }
 
     static void checkHalfWeak(String file) throws Throwable {
--- a/test/tools/launcher/ArgsEnvVar.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/tools/launcher/ArgsEnvVar.java	Thu Feb 09 18:10:19 2017 +0000
@@ -40,7 +40,7 @@
     private static File testJar = null;
     private static Map<String, String> env = new HashMap<>();
 
-    private static String JAVA_OPTIONS = "JAVA_OPTIONS";
+    private static String JDK_JAVA_OPTIONS = "JDK_JAVA_OPTIONS";
 
     static void init() throws IOException {
         if  (testJar != null) {
@@ -105,7 +105,7 @@
         File argFile2 = createArgFile("argFile2", List.of("-Darg.file2=TWO"));
         File argFile3 = createArgFile("argFile3", List.of("-Darg.file3=THREE"));
 
-        env.put(JAVA_OPTIONS, "@argFile1\n-Xint\r-cp @@escaped\t@argFile2");
+        env.put(JDK_JAVA_OPTIONS, "@argFile1\n-Xint\r-cp @@escaped\t@argFile2");
 
         TestResult tr = doExec(env, javaCmd, "@argFile3", "-cp", "test.jar", "Foo", "uarg1", "@uarg2");
 
@@ -133,13 +133,13 @@
     }
 
     private TestResult testInEnv(List<String> options) {
-        env.put(JAVA_OPTIONS, String.join(" ", options));
+        env.put(JDK_JAVA_OPTIONS, String.join(" ", options));
         return doExec(env, javaCmd, "-jar", "test.jar");
     }
 
     private TestResult testInEnvAsArgFile(List<String> options) throws IOException {
         File argFile = createArgFile("argFile", options);
-        env.put(JAVA_OPTIONS, "@argFile");
+        env.put(JDK_JAVA_OPTIONS, "@argFile");
         TestResult tr = doExec(env, javaCmd, "-jar", "test.jar");
         argFile.delete();
         return tr;
@@ -187,7 +187,7 @@
         File argFile1 = createArgFile("arg File 1", List.of("-Xint"));
         File argFile2 = createArgFile("arg File 2", List.of("-Dprop='value with spaces'"));
         File argFile3 = createArgFile("arg File 3", List.of("-Xmx32m"));
-        env.put(JAVA_OPTIONS, "'@arg File 1' @\"arg File 2\" @'arg File'\" 3\"");
+        env.put(JDK_JAVA_OPTIONS, "'@arg File 1' @\"arg File 2\" @'arg File'\" 3\"");
 
         TestResult tr = doExec(env, javaCmd, "-jar", "test.jar");
         List<String> options = new ArrayList<>();
@@ -204,7 +204,7 @@
 
     @Test
     public void openQuoteShouldFail() {
-        env.put(JAVA_OPTIONS, "-Dprop='value missing close quote");
+        env.put(JDK_JAVA_OPTIONS, "-Dprop='value missing close quote");
         TestResult tr = doExec(env, javaCmd, "-version");
         tr.checkNegative();
         if (!tr.testStatus) {
@@ -215,11 +215,11 @@
 
     @Test
     public void noWildcard() {
-        env.put(JAVA_OPTIONS, "-cp *");
+        env.put(JDK_JAVA_OPTIONS, "-cp *");
         TestResult tr = doExec(env, javaCmd, "-jar", "test.jar");
         verifyOptions(List.of("-cp", "*", "-jar", "test.jar"), tr);
 
-        env.put(JAVA_OPTIONS, "-p ?");
+        env.put(JDK_JAVA_OPTIONS, "-p ?");
         tr = doExec(env, javaCmd, "-jar", "test.jar", "one", "two");
         verifyOptions(List.of("-p", "?", "-jar", "test.jar", "one", "two"), tr);
     }
--- a/test/tools/launcher/I18NArgTest.java	Thu Feb 09 17:21:47 2017 +0000
+++ b/test/tools/launcher/I18NArgTest.java	Thu Feb 09 18:10:19 2017 +0000
@@ -95,21 +95,19 @@
             throw new RuntimeException("test fails");
         }
 
-        // Test via JAVA_OPTIONS
-/*
+        // Test via JDK_JAVA_OPTIONS
         Map<String, String> env = new HashMap<>();
         String cmd = "-Dtest.src=" + TEST_SOURCES_DIR.getAbsolutePath() +
                 " -Dtest.classes=" + TEST_CLASSES_DIR.getAbsolutePath() +
                 " -cp " + TEST_CLASSES_DIR.getAbsolutePath() +
                 " I18NArgTest " + unicodeStr + " " + hexValue;
-        env.put("JAVA_OPTIONS", cmd);
+        env.put("JDK_JAVA_OPTIONS", cmd);
         tr = doExec(env, javaCmd);
         System.out.println(tr.testOutput);
         if (!tr.isOK()) {
             System.err.println(tr);
             throw new RuntimeException("test fails");
         }
-*/
     }
 
     static void testCharacters(String... args) {