--- a/make/InitSupport.gmk Tue Nov 28 15:01:00 2017 -0800
+++ b/make/InitSupport.gmk Wed Nov 29 09:07:01 2017 -0800
@@ -47,7 +47,7 @@
# Make control variables, handled by Init.gmk
INIT_CONTROL_VARIABLES += LOG CONF CONF_NAME SPEC JOBS TEST_JOBS CONF_CHECK \
- COMPARE_BUILD JTREG GTEST
+ COMPARE_BUILD JTREG GTEST TEST_OPTS TEST_VM_OPTS
# All known make control variables
MAKE_CONTROL_VARIABLES := $(INIT_CONTROL_VARIABLES) TEST JDK_FILTER
--- a/make/RunTests.gmk Tue Nov 28 15:01:00 2017 -0800
+++ b/make/RunTests.gmk Wed Nov 29 09:07:01 2017 -0800
@@ -32,11 +32,42 @@
# We will always run multiple tests serially
.NOTPARALLEL:
+################################################################################
+# Parse global control variables
+################################################################################
+
+ifneq ($(TEST_VM_OPTS), )
+ ifneq ($(TEST_OPTS), )
+ TEST_OPTS := $(TEST_OPTS);VM_OPTIONS=$(TEST_VM_OPTS)
+ else
+ TEST_OPTS := VM_OPTIONS=$(TEST_VM_OPTS)
+ endif
+endif
+
+$(eval $(call ParseKeywordVariable, TEST_OPTS, \
+ KEYWORDS := JOBS TIMEOUT, \
+ STRING_KEYWORDS := VM_OPTIONS, \
+))
+
+# Helper function to propagate TEST_OPTS values.
+#
+# Note: No spaces are allowed around the arguments.
+# Arg $1 The variable in TEST_OPTS to propagate
+# Arg $2 The control variable to propagate it to
+define SetTestOpt
+ ifneq ($$(TEST_OPTS_$1), )
+ $2_$1 := $$(TEST_OPTS_$1)
+ endif
+endef
+
+################################################################################
# Hook to include the corresponding custom file, if present.
$(eval $(call IncludeCustomExtension, RunTests.gmk))
+################################################################################
TEST_RESULTS_DIR := $(OUTPUTDIR)/test-results
TEST_SUPPORT_DIR := $(OUTPUTDIR)/test-support
+TEST_SUMMARY := $(TEST_RESULTS_DIR)/test-summary.txt
ifeq ($(CUSTOM_ROOT), )
JTREG_TOPDIR := $(TOPDIR)
@@ -48,6 +79,17 @@
# Parse control variables
################################################################################
+ifneq ($(TEST_OPTS), )
+ # Inform the user
+ $(info Running tests using TEST_OPTS control variable '$(TEST_OPTS)')
+
+ $(eval $(call SetTestOpt,VM_OPTIONS,JTREG))
+ $(eval $(call SetTestOpt,VM_OPTIONS,GTEST))
+
+ $(eval $(call SetTestOpt,JOBS,JTREG))
+ $(eval $(call SetTestOpt,TIMEOUT,JTREG))
+endif
+
$(eval $(call ParseKeywordVariable, JTREG, \
KEYWORDS := JOBS TIMEOUT TEST_MODE ASSERT VERBOSE RETAIN MAX_MEM, \
STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS, \
@@ -60,7 +102,7 @@
$(eval $(call ParseKeywordVariable, GTEST, \
KEYWORDS := REPEAT, \
- STRING_KEYWORDS := OPTIONS, \
+ STRING_KEYWORDS := OPTIONS VM_OPTIONS, \
))
ifneq ($(GTEST), )
@@ -280,7 +322,7 @@
$$(FIXPATH) $$(TEST_IMAGE_DIR)/hotspot/gtest/server/gtestLauncher \
-jdk $(JDK_IMAGE_DIR) $$($1_GTEST_FILTER) \
--gtest_output=xml:$$($1_TEST_RESULTS_DIR)/gtest.xml \
- $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) \
+ $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) $$(GTEST_VM_OPTIONS) \
> >($(TEE) $$($1_TEST_RESULTS_DIR)/gtest.txt) || true )
$1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/gtest.txt
@@ -289,15 +331,24 @@
$$(call LogWarn, Finished running test '$$($1_TEST)')
$$(call LogWarn, Test report is stored in $$(strip \
$$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
- $$(eval $1_TOTAL := $$(shell $$(AWK) '/==========.* tests? from .* \
- test cases? ran/ { print $$$$2 }' $$($1_RESULT_FILE)))
- $$(eval $1_PASSED := $$(shell $$(AWK) '/\[ PASSED \] .* tests?./ \
- { print $$$$4 }' $$($1_RESULT_FILE)))
- $$(eval $1_FAILED := $$(shell $$(AWK) '/\[ FAILED \] .* tests?, \
- listed below/ { print $$$$4 }' $$($1_RESULT_FILE)))
- $$(if $$($1_FAILED), , $$(eval $1_FAILED := 0))
- $$(eval $1_ERROR := $$(shell \
- $$(EXPR) $$($1_TOTAL) - $$($1_PASSED) - $$($1_FAILED)))
+ $$(if $$(wildcard $$($1_RESULT_FILE)), \
+ $$(eval $1_TOTAL := $$(shell $$(AWK) '/==========.* tests? from .* \
+ test cases? ran/ { print $$$$2 }' $$($1_RESULT_FILE))) \
+ $$(if $$($1_TOTAL), , $$(eval $1_TOTAL := 0)) \
+ $$(eval $1_PASSED := $$(shell $$(AWK) '/\[ PASSED \] .* tests?./ \
+ { print $$$$4 }' $$($1_RESULT_FILE))) \
+ $$(if $$($1_PASSED), , $$(eval $1_PASSED := 0)) \
+ $$(eval $1_FAILED := $$(shell $$(AWK) '/\[ FAILED \] .* tests?, \
+ listed below/ { print $$$$4 }' $$($1_RESULT_FILE))) \
+ $$(if $$($1_FAILED), , $$(eval $1_FAILED := 0)) \
+ $$(eval $1_ERROR := $$(shell \
+ $$(EXPR) $$($1_TOTAL) - $$($1_PASSED) - $$($1_FAILED))) \
+ , \
+ $$(eval $1_PASSED := 0) \
+ $$(eval $1_FAILED := 0) \
+ $$(eval $1_ERROR := 1) \
+ $$(eval $1_TOTAL := 1) \
+ )
$1: run-test-$1 parse-test-$1
@@ -521,42 +572,46 @@
TEST_FAILURE := false
run-test: $(TARGETS)
- # Print a table of the result of all tests run and their result
- $(ECHO)
- $(ECHO) ==============================
- $(ECHO) Test summary
- $(ECHO) ==============================
- $(PRINTF) "%2s %-49s %5s %5s %5s %5s %2s\n" " " TEST \
- TOTAL PASS FAIL ERROR " "
+ # Create and print a table of the result of all tests run
+ $(RM) $(TEST_SUMMARY).old 2> /dev/null
+ $(MV) $(TEST_SUMMARY) $(TEST_SUMMARY).old 2> /dev/null || true
+ $(ECHO) >> $(TEST_SUMMARY) ==============================
+ $(ECHO) >> $(TEST_SUMMARY) Test summary
+ $(ECHO) >> $(TEST_SUMMARY) ==============================
+ $(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s %5s %5s %5s %5s %2s\n" " " \
+ TEST TOTAL PASS FAIL ERROR " "
$(foreach test, $(TESTS_TO_RUN), \
$(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \
$(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \
$(eval NAME_PATTERN := $(shell $(ECHO) $(test) | $(TR) -c \\n _)) \
$(if $(filter __________________________________________________%, $(NAME_PATTERN)), \
$(eval TEST_NAME := ) \
- $(PRINTF) "%2s %-49s\n" " " "$(test)" $(NEWLINE) \
+ $(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s\n" " " "$(test)" $(NEWLINE) \
, \
$(eval TEST_NAME := $(test)) \
) \
$(if $(filter $($(TEST_ID)_PASSED), $($(TEST_ID)_TOTAL)), \
- $(PRINTF) "%2s %-49s %5d %5d %5d %5d %2s\n" " " "$(TEST_NAME)" \
- $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) $($(TEST_ID)_FAILED) \
- $($(TEST_ID)_ERROR) " " $(NEWLINE) \
+ $(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s %5d %5d %5d %5d %2s\n" \
+ " " "$(TEST_NAME)" $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) \
+ $($(TEST_ID)_FAILED) $($(TEST_ID)_ERROR) " " $(NEWLINE) \
, \
- $(PRINTF) "%2s %-49s %5d %5d %5d %5d %2s\n" ">>" "$(TEST_NAME)" \
- $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) $($(TEST_ID)_FAILED) \
- $($(TEST_ID)_ERROR) "<<" $(NEWLINE) \
+ $(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s %5d %5d %5d %5d %2s\n" \
+ ">>" "$(TEST_NAME)" $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) \
+ $($(TEST_ID)_FAILED) $($(TEST_ID)_ERROR) "<<" $(NEWLINE) \
$(eval TEST_FAILURE := true) \
) \
)
- $(ECHO) ==============================
+ $(ECHO) >> $(TEST_SUMMARY) ==============================
$(if $(filter true, $(TEST_FAILURE)), \
- $(ECHO) TEST FAILURE $(NEWLINE) \
+ $(ECHO) >> $(TEST_SUMMARY) TEST FAILURE $(NEWLINE) \
+ $(MKDIR) -p $(MAKESUPPORT_OUTPUTDIR) $(NEWLINE) \
$(TOUCH) $(MAKESUPPORT_OUTPUTDIR)/exit-with-error \
, \
- $(ECHO) TEST SUCCESS \
+ $(ECHO) >> $(TEST_SUMMARY) TEST SUCCESS \
)
$(ECHO)
+ $(CAT) $(TEST_SUMMARY)
+ $(ECHO)
################################################################################
--- a/make/nashorn/build.xml Tue Nov 28 15:01:00 2017 -0800
+++ b/make/nashorn/build.xml Wed Nov 29 09:07:01 2017 -0800
@@ -115,11 +115,11 @@
</target>
- <!-- check minimum ant version required to be 1.8.4 -->
+ <!-- check minimum ant version required to be 1.9.5 -->
<target name="check-ant-version">
- <property name="ant.version.required" value="1.8.4"/>
+ <property name="ant.version.required" value="1.9.5"/>
<antversion property="ant.current.version" />
- <fail message="The current ant version, ${ant.current.version}, is too old. Please use 1.8.4 or above.">
+ <fail message="The current ant version, ${ant.current.version}, is too old. Please use 1.9.5 or above.">
<condition>
<not>
<antversion atleast="${ant.version.required}"/>
--- a/src/java.base/share/classes/java/lang/ClassLoader.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java Wed Nov 29 09:07:01 2017 -0800
@@ -1813,7 +1813,7 @@
}
/**
- * Returns the platform class loader for delegation. All
+ * Returns the platform class loader. All
* <a href="#builtinLoaders">platform classes</a> are visible to
* the platform class loader.
*
@@ -1843,7 +1843,7 @@
}
/**
- * Returns the system class loader for delegation. This is the default
+ * Returns the system class loader. This is the default
* delegation parent for new {@code ClassLoader} instances, and is
* typically the class loader used to start the application.
*
@@ -1884,7 +1884,7 @@
* the application module path then the class path defaults to
* the current working directory.
*
- * @return The system {@code ClassLoader} for delegation
+ * @return The system {@code ClassLoader}
*
* @throws SecurityException
* If a security manager is present, and the caller's class loader
--- a/src/java.base/share/classes/java/security/interfaces/DSAKeyPairGenerator.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/java.base/share/classes/java/security/interfaces/DSAKeyPairGenerator.java Wed Nov 29 09:07:01 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, 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
@@ -32,9 +32,12 @@
*
* <p>The {@code initialize} methods may each be called any number
* of times. If no {@code initialize} method is called on a
- * DSAKeyPairGenerator, the default is to generate 1024-bit keys, using
- * precomputed p, q and g parameters and an instance of SecureRandom as
- * the random bit source.
+ * DSAKeyPairGenerator, each provider that implements this interface
+ * should supply (and document) a default initialization. Note that
+ * defaults may vary across different providers. Additionally, the default
+ * value for a provider may change in a future version. Therefore, it is
+ * recommended to explicitly initialize the DSAKeyPairGenerator instead
+ * of relying on provider-specific defaults.
*
* <p>Users wishing to indicate DSA-specific parameters, and to generate a key
* pair suitable for use with the DSA algorithm typically
@@ -45,12 +48,13 @@
* KeyPairGenerator {@code getInstance} method with "DSA"
* as its argument.
*
- * <li>Initialize the generator by casting the result to a DSAKeyPairGenerator
- * and calling one of the
- * {@code initialize} methods from this DSAKeyPairGenerator interface.
+ * <li>Check if the returned key pair generator is an instance of
+ * DSAKeyPairGenerator before casting the result to a DSAKeyPairGenerator
+ * and calling one of the {@code initialize} methods from this
+ * DSAKeyPairGenerator interface.
*
* <li>Generate a key pair by calling the {@code generateKeyPair}
- * method from the KeyPairGenerator class.
+ * method of the KeyPairGenerator class.
*
* </ol>
*
@@ -63,7 +67,7 @@
* parameters.
*
* <p>Note: Some earlier implementations of this interface may not support
- * larger sizes of DSA parameters such as 2048 and 3072-bit.
+ * larger values of DSA parameters such as 3072-bit.
*
* @since 1.1
* @see java.security.KeyPairGenerator
@@ -97,8 +101,7 @@
* p, q and g parameters. If it is false, the method uses precomputed
* parameters for the modulus length requested. If there are no
* precomputed parameters for that modulus length, an exception will be
- * thrown. It is guaranteed that there will always be
- * default parameters for modulus lengths of 512 and 1024 bits.
+ * thrown.
*
* @param modlen the modulus length in bits. Valid values are any
* multiple of 64 between 512 and 1024, inclusive, 2048, and 3072.
--- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Wed Nov 29 09:07:01 2017 -0800
@@ -257,7 +257,7 @@
*
* @implSpec This implementation dispatches to the visit method for
* the specific {@linkplain TypeKind kind} of pseudo-type:
- * {@code VOID}, {@code PACKAGE}, or {@code NONE}.
+ * {@code VOID}, {@code PACKAGE}, {@code MODULE}, or {@code NONE}.
*
* @param t {@inheritDoc}
* @param p {@inheritDoc}
@@ -273,6 +273,9 @@
case PACKAGE:
return visitNoTypeAsPackage(t, p);
+ case MODULE:
+ return visitNoTypeAsModule(t, p);
+
case NONE:
return visitNoTypeAsNone(t, p);
@@ -308,6 +311,21 @@
}
/**
+ * Visits a {@link TypeKind#MODULE MODULE} pseudo-type.
+ *
+ * @implSpec This implementation calls {@code visitUnknown}.
+ *
+ * @param t the type to visit
+ * @param p a visitor-specified parameter
+ * @return the result of {@code visitUnknown}
+ *
+ * @since 10
+ */
+ public R visitNoTypeAsModule(NoType t, P p) {
+ return visitUnknown(t, p);
+ }
+
+ /**
* Visits a {@link TypeKind#NONE NONE} pseudo-type.
*
* @implSpec This implementation calls {@code defaultAction}.
--- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor9.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor9.java Wed Nov 29 09:07:01 2017 -0800
@@ -93,4 +93,20 @@
protected TypeKindVisitor9(R defaultValue) {
super(defaultValue);
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @implSpec This implementation calls {@code defaultAction}.
+ *
+ * @param t {@inheritDoc}
+ * @param p {@inheritDoc}
+ * @return the result of {@code defaultAction}
+ *
+ * @since 10
+ */
+ @Override
+ public R visitNoTypeAsModule(NoType t, P p) {
+ return defaultAction(t, p);
+ }
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Wed Nov 29 09:07:01 2017 -0800
@@ -63,6 +63,7 @@
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Options;
+import com.sun.tools.javac.util.Position;
import java.util.EnumSet;
import java.util.HashMap;
@@ -305,7 +306,7 @@
JCMethodDecl md = (JCMethodDecl)decls(oldTree.def).head;
List<JCVariableDecl> params = md.params;
JCBlock body = md.body;
- JCLambda newTree = make.Lambda(params, body);
+ JCLambda newTree = make.at(oldTree).Lambda(params, body);
return List.of(newTree);
}
@@ -418,7 +419,7 @@
List<JCEnhancedForLoop> rewrite(JCEnhancedForLoop oldTree) {
JCEnhancedForLoop newTree = copier.copy(oldTree);
newTree.var = rewriteVarType(oldTree.var);
- newTree.body = make.Block(0, List.nil());
+ newTree.body = make.at(oldTree.body).Block(0, List.nil());
return List.of(newTree);
}
@Override
@@ -551,7 +552,8 @@
JCStatement treeToAnalyze = (JCStatement)rewriting.originalTree;
if (rewriting.env.info.scope.owner.kind == Kind.TYP) {
//add a block to hoist potential dangling variable declarations
- treeToAnalyze = make.Block(Flags.SYNTHETIC, List.of((JCStatement)rewriting.originalTree));
+ treeToAnalyze = make.at(Position.NOPOS)
+ .Block(Flags.SYNTHETIC, List.of((JCStatement)rewriting.originalTree));
}
//TODO: to further refine the analysis, try all rewriting combinations
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java Wed Nov 29 09:07:01 2017 -0800
@@ -57,6 +57,7 @@
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DiagnosticSource;
+import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
@@ -98,6 +99,7 @@
protected static final Context.Key<ArgumentAttr> methodAttrKey = new Context.Key<>();
private final DeferredAttr deferredAttr;
+ private final JCDiagnostic.Factory diags;
private final Attr attr;
private final Symtab syms;
private final Log log;
@@ -121,6 +123,7 @@
protected ArgumentAttr(Context context) {
context.put(methodAttrKey, this);
deferredAttr = DeferredAttr.instance(context);
+ diags = JCDiagnostic.Factory.instance(context);
attr = Attr.instance(context);
syms = Symtab.instance(context);
log = Log.instance(context);
@@ -482,18 +485,14 @@
List<JCReturn> returnExpressions() {
return returnExpressions.orElseGet(() -> {
final List<JCReturn> res;
- if (speculativeTree.getBodyKind() == BodyKind.EXPRESSION) {
- res = List.of(attr.make.Return((JCExpression)speculativeTree.body));
- } else {
- ListBuffer<JCReturn> returnExpressions = new ListBuffer<>();
- new LambdaReturnScanner() {
- @Override
- public void visitReturn(JCReturn tree) {
- returnExpressions.add(tree);
- }
- }.scan(speculativeTree.body);
- res = returnExpressions.toList();
- }
+ ListBuffer<JCReturn> buf = new ListBuffer<>();
+ new LambdaReturnScanner() {
+ @Override
+ public void visitReturn(JCReturn tree) {
+ buf.add(tree);
+ }
+ }.scan(speculativeTree.body);
+ res = buf.toList();
returnExpressions = Optional.of(res);
return res;
});
@@ -519,16 +518,38 @@
private void checkLambdaCompatible(Type descriptor, ResultInfo resultInfo) {
CheckContext checkContext = resultInfo.checkContext;
ResultInfo bodyResultInfo = attr.lambdaBodyResult(speculativeTree, descriptor, resultInfo);
- for (JCReturn ret : returnExpressions()) {
- Type t = getReturnType(ret);
- if (speculativeTree.getBodyKind() == BodyKind.EXPRESSION || !t.hasTag(VOID)) {
- checkSpeculative(ret.expr, t, bodyResultInfo);
- }
+ switch (speculativeTree.getBodyKind()) {
+ case EXPRESSION:
+ checkSpeculative(speculativeTree.body, speculativeTree.body.type, bodyResultInfo);
+ break;
+ case STATEMENT:
+ for (JCReturn ret : returnExpressions()) {
+ checkReturnInStatementLambda(ret, bodyResultInfo);
+ }
+ break;
}
attr.checkLambdaCompatible(speculativeTree, descriptor, checkContext);
}
+ /**
+ * This is an inlined version of {@link Attr#visitReturn(JCReturn)}.
+ */
+ void checkReturnInStatementLambda(JCReturn ret, ResultInfo resultInfo) {
+ if (resultInfo.pt.hasTag(VOID) && ret.expr != null) {
+ //fail - if the function type's result is void, the lambda body must be a void-compatible block.
+ resultInfo.checkContext.report(speculativeTree.pos(),
+ diags.fragment("unexpected.ret.val"));
+ } else if (!resultInfo.pt.hasTag(VOID)) {
+ if (ret.expr == null) {
+ //fail - if the function type's result is non-void, the lambda body must be a value-compatible block.
+ resultInfo.checkContext.report(speculativeTree.pos(),
+ diags.fragment("missing.ret.val"));
+ }
+ checkSpeculative(ret.expr, ret.expr.type, resultInfo);
+ }
+ }
+
/** Get the type associated with given return expression. */
Type getReturnType(JCReturn ret) {
if (ret.expr == null) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Wed Nov 29 09:07:01 2017 -0800
@@ -3557,18 +3557,19 @@
Scope staticallyImportedSoFar, Scope topLevelScope,
Symbol sym, boolean staticImport) {
Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous();
- Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates);
- if (clashing == null && !staticImport) {
- clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates);
+ Symbol ordinaryClashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates);
+ Symbol staticClashing = null;
+ if (ordinaryClashing == null && !staticImport) {
+ staticClashing = staticallyImportedSoFar.findFirst(sym.name, duplicates);
}
- if (clashing != null) {
- if (staticImport)
- log.error(pos, Errors.AlreadyDefinedStaticSingleImport(clashing));
+ if (ordinaryClashing != null || staticClashing != null) {
+ if (ordinaryClashing != null)
+ log.error(pos, Errors.AlreadyDefinedSingleImport(ordinaryClashing));
else
- log.error(pos, Errors.AlreadyDefinedSingleImport(clashing));
+ log.error(pos, Errors.AlreadyDefinedStaticSingleImport(staticClashing));
return false;
}
- clashing = topLevelScope.findFirst(sym.name, duplicates);
+ Symbol clashing = topLevelScope.findFirst(sym.name, duplicates);
if (clashing != null) {
log.error(pos, Errors.AlreadyDefinedThisUnit(clashing));
return false;
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanLinker.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanLinker.java Wed Nov 29 09:07:01 2017 -0800
@@ -91,6 +91,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.function.Function;
import jdk.dynalink.CallSiteDescriptor;
import jdk.dynalink.Namespace;
import jdk.dynalink.Operation;
@@ -189,85 +190,126 @@
assertParameterCount(callSiteDescriptor, isFixedKey ? 1 : 2);
final LinkerServices linkerServices = req.linkerServices;
final MethodType callSiteType = callSiteDescriptor.getMethodType();
- final Class<?> declaredType = callSiteType.parameterType(0);
final GuardedInvocationComponent nextComponent = getNextComponent(req);
+ final GuardedInvocationComponentAndCollectionType gicact = guardedInvocationComponentAndCollectionType(
+ callSiteType, linkerServices, MethodHandles::arrayElementGetter, GET_LIST_ELEMENT, GET_MAP_ELEMENT);
+
+ if (gicact == null) {
+ // Can't retrieve elements for objects that are neither arrays, nor list, nor maps.
+ return nextComponent;
+ }
+
+ final Object typedName = getTypedName(name, gicact.collectionType == CollectionType.MAP, linkerServices);
+ if (typedName == INVALID_NAME) {
+ return nextComponent;
+ }
+
+ return guardComponentWithRangeCheck(gicact, linkerServices,
+ callSiteDescriptor, nextComponent, new Binder(linkerServices, callSiteType, typedName),
+ isFixedKey ? NULL_GETTER_1 : NULL_GETTER_2);
+ }
+
+ private static class GuardedInvocationComponentAndCollectionType {
+ final GuardedInvocationComponent gic;
+ final CollectionType collectionType;
+
+ GuardedInvocationComponentAndCollectionType(final GuardedInvocationComponent gic, final CollectionType collectionType) {
+ this.gic = gic;
+ this.collectionType = collectionType;
+ }
+ }
+
+ private GuardedInvocationComponentAndCollectionType guardedInvocationComponentAndCollectionType(
+ final MethodType callSiteType, final LinkerServices linkerServices,
+ final Function<Class<?>, MethodHandle> arrayMethod, final MethodHandle listMethod, final MethodHandle mapMethod) {
+ final Class<?> declaredType = callSiteType.parameterType(0);
// If declared type of receiver at the call site is already an array, a list or map, bind without guard. Thing
// is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance they're
// dealing with an array, or a list or map, but hey...
// Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
// in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
- final GuardedInvocationComponent gic;
- final CollectionType collectionType;
if(declaredType.isArray()) {
- gic = createInternalFilteredGuardedInvocationComponent(MethodHandles.arrayElementGetter(declaredType), linkerServices);
- collectionType = CollectionType.ARRAY;
+ return new GuardedInvocationComponentAndCollectionType(
+ createInternalFilteredGuardedInvocationComponent(arrayMethod.apply(declaredType), linkerServices),
+ CollectionType.ARRAY);
} else if(List.class.isAssignableFrom(declaredType)) {
- gic = createInternalFilteredGuardedInvocationComponent(GET_LIST_ELEMENT, linkerServices);
- collectionType = CollectionType.LIST;
+ return new GuardedInvocationComponentAndCollectionType(
+ createInternalFilteredGuardedInvocationComponent(listMethod, linkerServices),
+ CollectionType.LIST);
} else if(Map.class.isAssignableFrom(declaredType)) {
- gic = createInternalFilteredGuardedInvocationComponent(GET_MAP_ELEMENT, linkerServices);
- collectionType = CollectionType.MAP;
+ return new GuardedInvocationComponentAndCollectionType(
+ createInternalFilteredGuardedInvocationComponent(mapMethod, linkerServices),
+ CollectionType.MAP);
} else if(clazz.isArray()) {
- gic = getClassGuardedInvocationComponent(linkerServices.filterInternalObjects(MethodHandles.arrayElementGetter(clazz)), callSiteType);
- collectionType = CollectionType.ARRAY;
+ return new GuardedInvocationComponentAndCollectionType(
+ getClassGuardedInvocationComponent(linkerServices.filterInternalObjects(arrayMethod.apply(clazz)), callSiteType),
+ CollectionType.ARRAY);
} else if(List.class.isAssignableFrom(clazz)) {
- gic = createInternalFilteredGuardedInvocationComponent(GET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class, ValidationType.INSTANCE_OF,
- linkerServices);
- collectionType = CollectionType.LIST;
+ return new GuardedInvocationComponentAndCollectionType(
+ createInternalFilteredGuardedInvocationComponent(listMethod, Guards.asType(LIST_GUARD, callSiteType),
+ List.class, ValidationType.INSTANCE_OF, linkerServices),
+ CollectionType.LIST);
} else if(Map.class.isAssignableFrom(clazz)) {
- gic = createInternalFilteredGuardedInvocationComponent(GET_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class, ValidationType.INSTANCE_OF,
- linkerServices);
- collectionType = CollectionType.MAP;
- } else {
- // Can't retrieve elements for objects that are neither arrays, nor list, nor maps.
- return nextComponent;
+ return new GuardedInvocationComponentAndCollectionType(
+ createInternalFilteredGuardedInvocationComponent(mapMethod, Guards.asType(MAP_GUARD, callSiteType),
+ Map.class, ValidationType.INSTANCE_OF, linkerServices),
+ CollectionType.MAP);
}
+ return null;
+ }
+ private static final Object INVALID_NAME = new Object();
+
+ private static Object getTypedName(final Object name, final boolean isMap, final LinkerServices linkerServices) throws Exception {
// Convert the key to a number if we're working with a list or array
- final Object typedName;
- if (collectionType != CollectionType.MAP && isFixedKey) {
+ if (!isMap && name != null) {
final Integer integer = convertKeyToInteger(name, linkerServices);
if (integer == null || integer.intValue() < 0) {
// key is not a non-negative integer, it can never address an
// array or list element
- return nextComponent;
+ return INVALID_NAME;
}
- typedName = integer;
- } else {
- typedName = name;
+ return integer;
}
+ return name;
+ }
- final GuardedInvocation gi = gic.getGuardedInvocation();
- final Binder binder = new Binder(linkerServices, callSiteType, typedName);
- final MethodHandle invocation = gi.getInvocation();
+ private static GuardedInvocationComponent guardComponentWithRangeCheck(
+ final GuardedInvocationComponentAndCollectionType gicact, final LinkerServices linkerServices,
+ final CallSiteDescriptor callSiteDescriptor, final GuardedInvocationComponent nextComponent, final Binder binder,
+ final MethodHandle noOp) {
+ final MethodType callSiteType = callSiteDescriptor.getMethodType();
final MethodHandle checkGuard;
- switch(collectionType) {
- case LIST:
- checkGuard = convertArgToNumber(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor);
- break;
- case MAP:
- checkGuard = linkerServices.filterInternalObjects(CONTAINS_MAP);
- break;
- case ARRAY:
- checkGuard = convertArgToNumber(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
- break;
- default:
- throw new AssertionError();
+ switch(gicact.collectionType) {
+ case LIST:
+ checkGuard = convertArgToNumber(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor);
+ break;
+ case MAP:
+ checkGuard = linkerServices.filterInternalObjects(CONTAINS_MAP);
+ break;
+ case ARRAY:
+ checkGuard = convertArgToNumber(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
+ break;
+ default:
+ throw new AssertionError();
}
- // If there's no next component, produce a fixed null-returning one
+ // If there's no next component, produce a fixed no-op one
final GuardedInvocationComponent finalNextComponent;
if (nextComponent != null) {
finalNextComponent = nextComponent;
} else {
- final MethodHandle nullGetterHandle = isFixedKey ? NULL_GETTER_1 : NULL_GETTER_2;
- finalNextComponent = createGuardedInvocationComponentAsType(nullGetterHandle, callSiteType, linkerServices);
+ finalNextComponent = createGuardedInvocationComponentAsType(noOp, callSiteType, linkerServices);
}
- final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation),
+ final GuardedInvocationComponent gic = gicact.gic;
+ final GuardedInvocation gi = gic.getGuardedInvocation();
+
+ final MethodPair matchedInvocations = matchReturnTypes(binder.bind(gi.getInvocation()),
finalNextComponent.getGuardedInvocation().getInvocation());
+
return finalNextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(),
gic.getValidatorClass(), gic.getValidationType());
}
@@ -435,90 +477,37 @@
assertParameterCount(callSiteDescriptor, isFixedKey ? 2 : 3);
final LinkerServices linkerServices = req.linkerServices;
final MethodType callSiteType = callSiteDescriptor.getMethodType();
- final Class<?> declaredType = callSiteType.parameterType(0);
+
+ final GuardedInvocationComponentAndCollectionType gicact = guardedInvocationComponentAndCollectionType(
+ callSiteType, linkerServices, MethodHandles::arrayElementSetter, SET_LIST_ELEMENT, PUT_MAP_ELEMENT);
- final GuardedInvocationComponent gic;
- // If declared type of receiver at the call site is already an array, a list or map, bind without guard. Thing
- // is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance they're
- // dealing with an array, or a list or map, but hey...
- // Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
- // in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
- final CollectionType collectionType;
- if(declaredType.isArray()) {
- gic = createInternalFilteredGuardedInvocationComponent(MethodHandles.arrayElementSetter(declaredType), linkerServices);
- collectionType = CollectionType.ARRAY;
- } else if(List.class.isAssignableFrom(declaredType)) {
- gic = createInternalFilteredGuardedInvocationComponent(SET_LIST_ELEMENT, linkerServices);
- collectionType = CollectionType.LIST;
- } else if(Map.class.isAssignableFrom(declaredType)) {
- gic = createInternalFilteredGuardedInvocationComponent(PUT_MAP_ELEMENT, linkerServices);
- collectionType = CollectionType.MAP;
- } else if(clazz.isArray()) {
- gic = getClassGuardedInvocationComponent(linkerServices.filterInternalObjects(
- MethodHandles.arrayElementSetter(clazz)), callSiteType);
- collectionType = CollectionType.ARRAY;
- } else if(List.class.isAssignableFrom(clazz)) {
- gic = createInternalFilteredGuardedInvocationComponent(SET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class, ValidationType.INSTANCE_OF,
- linkerServices);
- collectionType = CollectionType.LIST;
- } else if(Map.class.isAssignableFrom(clazz)) {
- gic = createInternalFilteredGuardedInvocationComponent(PUT_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType),
- Map.class, ValidationType.INSTANCE_OF, linkerServices);
- collectionType = CollectionType.MAP;
- } else {
- // Can't set elements for objects that are neither arrays, nor list, nor maps.
- gic = null;
- collectionType = null;
+ if(gicact == null) {
+ return getNextComponent(req);
}
+ final boolean isMap = gicact.collectionType == CollectionType.MAP;
+
// In contrast to, say, getElementGetter, we only compute the nextComponent if the target object is not a map,
// as maps will always succeed in setting the element and will never need to fall back to the next component
// operation.
- final GuardedInvocationComponent nextComponent = collectionType == CollectionType.MAP ? null : getNextComponent(req);
- if(gic == null) {
+ final GuardedInvocationComponent nextComponent = isMap ? null : getNextComponent(req);
+
+ final Object typedName = getTypedName(name, isMap, linkerServices);
+ if (typedName == INVALID_NAME) {
return nextComponent;
}
- // Convert the key to a number if we're working with a list or array
- final Object typedName;
- if (collectionType != CollectionType.MAP && isFixedKey) {
- final Integer integer = convertKeyToInteger(name, linkerServices);
- if (integer == null || integer.intValue() < 0) {
- // key is not a non-negative integer, it can never address an
- // array or list element
- return nextComponent;
- }
- typedName = integer;
- } else {
- typedName = name;
- }
-
+ final GuardedInvocationComponent gic = gicact.gic;
final GuardedInvocation gi = gic.getGuardedInvocation();
final Binder binder = new Binder(linkerServices, callSiteType, typedName);
final MethodHandle invocation = gi.getInvocation();
- if (collectionType == CollectionType.MAP) {
- assert nextComponent == null;
+ if (isMap) {
return gic.replaceInvocation(binder.bind(invocation));
}
- assert collectionType == CollectionType.LIST || collectionType == CollectionType.ARRAY;
- final MethodHandle checkGuard = convertArgToNumber(collectionType == CollectionType.LIST ? RANGE_CHECK_LIST :
- RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
-
- // If there's no next component, produce a no-op one.
- final GuardedInvocationComponent finalNextComponent;
- if (nextComponent != null) {
- finalNextComponent = nextComponent;
- } else {
- final MethodHandle noOpSetterHandle = isFixedKey ? NO_OP_SETTER_2 : NO_OP_SETTER_3;
- finalNextComponent = createGuardedInvocationComponentAsType(noOpSetterHandle, callSiteType, linkerServices);
- }
-
- final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation),
- finalNextComponent.getGuardedInvocation().getInvocation());
- return finalNextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(),
- gic.getValidatorClass(), gic.getValidationType());
+ return guardComponentWithRangeCheck(gicact, linkerServices, callSiteDescriptor,
+ nextComponent, binder, isFixedKey ? NO_OP_SETTER_2 : NO_OP_SETTER_3);
}
private static final MethodHandle GET_COLLECTION_LENGTH = Lookup.PUBLIC.findVirtual(Collection.class, "size",
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css Tue Nov 28 15:01:00 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css Wed Nov 29 09:07:01 2017 -0800
@@ -1,10 +1,16 @@
-/* Javadoc style sheet */
-/*
-Overall document style
-*/
+/*
+ * Javadoc style sheet
+ */
@import url('resources/fonts/dejavu.css');
+/*
+ * Styles for individual HTML elements.
+ *
+ * These are styles that are specific to individual HTML elements. Changing them affects the style of a particular
+ * HTML element throughout the page.
+ */
+
body {
background-color:#ffffff;
color:#353833;
@@ -41,9 +47,6 @@
padding-top:129px;
margin-top:-129px;
}
-.searchTagResult:before, .searchTagResult:target {
- color:red;
-}
pre {
font-family:'DejaVu Sans Mono', monospace;
font-size:14px;
@@ -91,9 +94,16 @@
sup {
font-size:8px;
}
+
/*
-Document title and Copyright styles
-*/
+ * Styles for HTML generated by javadoc.
+ *
+ * These are style classes that are used by the standard doclet to generate HTML documentation.
+ */
+
+/*
+ * Styles for document title and copyright.
+ */
.clear {
clear:both;
height:0px;
@@ -124,8 +134,8 @@
font-weight:bold;
}
/*
-Navigation bar styles
-*/
+ * Styles for navigation bar.
+ */
.bar {
background-color:#4D7A97;
color:#FFFFFF;
@@ -233,8 +243,8 @@
overflow:hidden;
}
/*
-Page header and footer styles
-*/
+ * Styles for page header and footer.
+ */
.header, .footer {
clear:both;
margin:0 20px;
@@ -277,8 +287,8 @@
font-size:13px;
}
/*
-Heading styles
-*/
+ * Styles for headings.
+ */
div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
background-color:#dee3e9;
border:1px solid #d0d9e0;
@@ -299,8 +309,8 @@
padding:0px 0 20px 0;
}
/*
-Page layout container styles
-*/
+ * Styles for page layout containers.
+ */
.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
clear:both;
padding:10px 20px;
@@ -346,8 +356,8 @@
display:inline;
}
/*
-List styles
-*/
+ * Styles for lists.
+ */
li.circle {
list-style:circle;
}
@@ -403,8 +413,8 @@
margin-bottom:1px;
}
/*
-Table styles
-*/
+ * Styles for tables.
+ */
.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary,
.requiresSummary, .packagesSummary, .providesSummary, .usesSummary {
width:100%;
@@ -529,7 +539,6 @@
position:relative;
background-color:#4D7A97;
float:left;
-
}
.rowColor th, .altColor th {
font-weight:normal;
@@ -601,8 +610,8 @@
background-color:#EEEEEF;
}
/*
-Content styles
-*/
+ * Styles for contents.
+ */
.description pre {
margin-top:0;
}
@@ -613,27 +622,22 @@
.docSummary {
padding:0;
}
-
ul.blockList ul.blockList ul.blockList li.blockList h3 {
font-style:normal;
}
-
div.block {
font-size:14px;
font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
}
-
td.colLast div {
padding-top:0px;
}
-
-
td.colLast a {
padding-bottom:3px;
}
/*
-Formatting effect styles
-*/
+ * Styles for formatting effect.
+ */
.sourceLineNo {
color:green;
padding:0 30px 0 0;
@@ -668,18 +672,16 @@
margin-right:10px;
display:inline-block;
}
-
div.block div.deprecationComment, div.block div.block span.emphasizedPhrase,
div.block div.block span.interfaceName {
font-style:normal;
}
-
div.contentContainer ul.blockList li.blockList h2 {
padding-bottom:0px;
}
/*
-IFRAME specific styles
-*/
+ * Styles for IFRAME.
+ */
.mainContainer {
margin:0 auto;
padding:0;
@@ -733,11 +735,14 @@
margin-bottom:30px;
}
/*
-HTML5 specific styles
-*/
+ * Styles specific to HTML5 elements.
+ */
main, nav, header, footer, section {
display:block;
}
+/*
+ * Styles for javadoc search.
+ */
.ui-autocomplete-category {
font-weight:bold;
font-size:15px;
@@ -802,7 +807,9 @@
font-style:italic;
font-size:12px;
}
-
+.searchTagResult:before, .searchTagResult:target {
+ color:red;
+}
.moduleGraph span {
display:none;
position:absolute;
@@ -838,20 +845,17 @@
margin-top: 10px;
margin-bottom: 10px;
}
-
table.borderless > caption,
table.plain > caption,
table.striped > caption {
font-weight: bold;
font-size: smaller;
}
-
table.borderless th, table.borderless td,
table.plain th, table.plain td,
table.striped th, table.striped td {
padding: 2px 5px;
}
-
table.borderless,
table.borderless > thead > tr > th, table.borderless > tbody > tr > th, table.borderless > tr > th,
table.borderless > thead > tr > td, table.borderless > tbody > tr > td, table.borderless > tr > td {
@@ -860,7 +864,6 @@
table.borderless > thead > tr, table.borderless > tbody > tr, table.borderless > tr {
background-color: transparent;
}
-
table.plain {
border-collapse: collapse;
border: 1px solid black;
@@ -872,7 +875,6 @@
table.plain > thead > tr > td, table.plain > tbody > tr > td, table.plain > tr > td {
border: 1px solid black;
}
-
table.striped {
border-collapse: collapse;
border: 1px solid black;
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SplitIntoFunctions.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SplitIntoFunctions.java Wed Nov 29 09:07:01 2017 -0800
@@ -306,10 +306,10 @@
@Override
public boolean enterVarNode(final VarNode varNode) {
- if (!inSplitNode()) {
+ // ES6 block scoped declarations are already placed at their proper position by splitter
+ if (!inSplitNode() || varNode.isBlockScoped()) {
return super.enterVarNode(varNode);
}
- assert !varNode.isBlockScoped(); //TODO: we must handle these too, but we currently don't
final Expression init = varNode.getInit();
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Splitter.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Splitter.java Wed Nov 29 09:07:01 2017 -0800
@@ -41,6 +41,7 @@
import jdk.nashorn.internal.ir.SplitNode;
import jdk.nashorn.internal.ir.Splittable;
import jdk.nashorn.internal.ir.Statement;
+import jdk.nashorn.internal.ir.VarNode;
import jdk.nashorn.internal.ir.visitor.SimpleNodeVisitor;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.logging.DebugLogger;
@@ -201,8 +202,9 @@
for (final Statement statement : block.getStatements()) {
final long weight = WeighNodes.weigh(statement, weightCache);
+ final boolean isBlockScopedVarNode = isBlockScopedVarNode(statement);
- if (statementsWeight + weight >= SPLIT_THRESHOLD || statement.isTerminal()) {
+ if (statementsWeight + weight >= SPLIT_THRESHOLD || statement.isTerminal() || isBlockScopedVarNode) {
if (!statements.isEmpty()) {
splits.add(createBlockSplitNode(block, function, statements, statementsWeight));
statements = new ArrayList<>();
@@ -210,7 +212,7 @@
}
}
- if (statement.isTerminal()) {
+ if (statement.isTerminal() || isBlockScopedVarNode) {
splits.add(statement);
} else {
statements.add(statement);
@@ -243,6 +245,10 @@
return new SplitNode(name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT));
}
+ private boolean isBlockScopedVarNode(final Statement statement) {
+ return statement instanceof VarNode && ((VarNode) statement).isBlockScoped();
+ }
+
@Override
public boolean enterBlock(final Block block) {
if (block.isCatchBlock()) {
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/SplitReturn.java Tue Nov 28 15:01:00 2017 -0800
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/SplitReturn.java Wed Nov 29 09:07:01 2017 -0800
@@ -25,6 +25,7 @@
package jdk.nashorn.internal.ir;
+import jdk.nashorn.internal.ir.annotations.Ignore;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
/**
@@ -37,6 +38,7 @@
private static final long serialVersionUID = 1L;
/** The sole instance of this AST node. */
+ @Ignore
public static final SplitReturn INSTANCE = new SplitReturn();
private SplitReturn() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/Cert.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,265 @@
+/*
+ * 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.
+ */
+
+/*
+ * The certificates and corresponding private keys used by the test.
+ * All of certificates uses relative weak key size and hash algorithm, then
+ * all JDK releases can load them. Accordingly, a custom java.security file is
+ * provided to make sure such weak key sizes and algorithms are not blocked by
+ * any JDK build.
+ */
+public enum Cert {
+
+ // This certificate is generated by the below command:
+ // openssl req -x509 -newkey rsa:1024 -days 7300 \
+ // -subj "/CN=RSA_SHA1_1024" -sha1 \
+ // -keyout key.pem -out cert.pem
+ RSA_SHA1_1024(
+ SignatureAlgorithm.RSA,
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIB/jCCAWegAwIBAgIJANPuKkD7/jxkMA0GCSqGSIb3DQEBBQUAMBgxFjAUBgNV\n" +
+ "BAMMDVJTQV9TSEExXzEwMjQwHhcNMTcwOTA3MDIwNTM0WhcNMzcwOTAyMDIwNTM0\n" +
+ "WjAYMRYwFAYDVQQDDA1SU0FfU0hBMV8xMDI0MIGfMA0GCSqGSIb3DQEBAQUAA4GN\n" +
+ "ADCBiQKBgQC3v7UeIxD5bdv4mqwcpah7sNxpI3IxUFzI2ao1g1jVzDPZt9Zawa3K\n" +
+ "H+m9al1Fg2X1dyNeRlbiXavcIZOQwZqNj08zJEwAdICP8iOnXQ2HUv5cpzArOPTu\n" +
+ "GY3flhf39xgiWsSdfb+cP0QsWNagNU8EtebbHndv8W+2K5JEdlpwQQIDAQABo1Aw\n" +
+ "TjAdBgNVHQ4EFgQU32KqdiGyzg39chNt/OwQzGOlUyAwHwYDVR0jBBgwFoAU32Kq\n" +
+ "diGyzg39chNt/OwQzGOlUyAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOB\n" +
+ "gQAWx8y45IIWWhy44cuQs0qcSDQihIvhXB3pvlpCNdfsSrVoaaH8lrOVjTC718ip\n" +
+ "fE1sF8I9niLHUg8WrAzdQRDsKyUhDUhEEJ7w1ffxwf8bcI9+NgWwEix0Dazzkub8\n" +
+ "2IRXuZ3dGwzoI54XtxvKMFH86nJEj4M/XQGrc9bnlhcn4g==\n" +
+ "-----END CERTIFICATE-----",
+ "30820278020100300d06092a864886f70d0101010500048202623082025e0201" +
+ "0002818100b7bfb51e2310f96ddbf89aac1ca5a87bb0dc69237231505cc8d9aa" +
+ "358358d5cc33d9b7d65ac1adca1fe9bd6a5d458365f577235e4656e25dabdc21" +
+ "9390c19a8d8f4f33244c0074808ff223a75d0d8752fe5ca7302b38f4ee198ddf" +
+ "9617f7f718225ac49d7dbf9c3f442c58d6a0354f04b5e6db1e776ff16fb62b92" +
+ "44765a7041020301000102818100b2c5afdf5c5a9d72c73b7eb0c9465b3fcc79" +
+ "0549d946255bc0861555ef2eb503f1c67757f400cfa7019996123020fb906d5b" +
+ "b66b789ffba90b16270cbd1fbfcf285a821dcdc78fd8f17f399eb231ce9724db" +
+ "af60f9dd20f3e57bb4c0f9fdc9069589b82d442dd868d48c031eb782e27f9e70" +
+ "8469f9b3d5b1b23cee5bf1b41781024100dec184ea77c2126c6bc0c01ba727b4" +
+ "642587d63811240932334dc80c7976e0f715f156e52b352a25e5c52542af2b5f" +
+ "68a29a9b68858f313c4375cc78ec03d859024100d32be8375f52cbe904002321" +
+ "6977aee83fa88bf536d4052d2ed578727d7b7e5aeef91fc52b34c1b6638c00f0" +
+ "4c6985fdaaa2d6e72adbcc7d10ed8bafff69da29024100ae8210acd6f13519b7" +
+ "38a3c7862636ce1610daa3c5d9e3526e9acad3eafc54b57d7d3a44029b7dcf7e" +
+ "b7f9beca1842806892929949b8aa2bb9f5b9202a55c0d1024100887dc0c2c9a2" +
+ "429a823374818c2207b3a631d304d443867505e884c9bbc1ae9228146e2c8b18" +
+ "b67ca52b411010d3c3ff89e366f454076dcd08bc01a5e8790ac102402321988a" +
+ "2003e19c878791d402a7c0acdd1b6dd27203ed88f86a0e3a390ee57c0cd277f3" +
+ "ea5df6440dbc8bdb4c8b3c28fc77e6991bc4ed3f4dc0619a5b953e8e"),
+
+ // This certificate is generated by the below command:
+ // openssl req -x509 -newkey rsa:1024 -days 7300 \
+ // -subj "/CN=www.example.com" -sha1 \
+ // -keyout key.pem -out cert.pem
+ RSA_EXAMPLE_SHA1_1024(
+ SignatureAlgorithm.RSA,
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICAjCCAWugAwIBAgIJAK6TC9eDtZg4MA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV\n" +
+ "BAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNzExMDIwNTA5NDRaFw0zNzEwMjgwNTA5\n" +
+ "NDRaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEF\n" +
+ "AAOBjQAwgYkCgYEAtt5kxFTzJuoxJR2UgeXUxCw7TfL3FeK3lCrU3vruBe3XKKvF\n" +
+ "oyCxf/B5ucm22gzMfOvJBWRg6KrNTrXGI1LtlmAYNDM5J0lK2N/neKOm3Qxe0d1W\n" +
+ "AZ1lwgrMNirsWu+r4UPNMq5UohL5nqVU9WwVa12t0GF3er3k32tMTBqSclcCAwEA\n" +
+ "AaNQME4wHQYDVR0OBBYEFNc8tKGfZdFyaY0ZslwGLt1kpRYAMB8GA1UdIwQYMBaA\n" +
+ "FNc8tKGfZdFyaY0ZslwGLt1kpRYAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF\n" +
+ "BQADgYEAc71ZO83YEw9WvhxDEng9tMYUhJnNZJss6+gfWjZ487aiEGnS+VgKsHWz\n" +
+ "DBLBrYe9Ag5L9f1HtPNheUbnhhBbQ607jOG/wfmpi4VoU3myB5uxOfeAZdXDOB5x\n" +
+ "bv3t7KcEhgmPjB/e123jrBK8qnAYmDlQVlkZScctB3I1OuA2Po4=\n" +
+ "-----END CERTIFICATE-----",
+ "30820277020100300d06092a864886f70d0101010500048202613082025d0201" +
+ "0002818100b6de64c454f326ea31251d9481e5d4c42c3b4df2f715e2b7942ad4" +
+ "defaee05edd728abc5a320b17ff079b9c9b6da0ccc7cebc9056460e8aacd4eb5" +
+ "c62352ed96601834333927494ad8dfe778a3a6dd0c5ed1dd56019d65c20acc36" +
+ "2aec5aefabe143cd32ae54a212f99ea554f56c156b5dadd061777abde4df6b4c" +
+ "4c1a927257020301000102818048af52bc1acbdededd13d4930fa28b9441c47c" +
+ "b222f5c6fc92df07676db3a815a61c9b51de0a03a347b10a609bd6459a0dd926" +
+ "38877261686a5c6bb1ca9e8ea2373870af7685e7d6cebd66faba65af2ef04bd9" +
+ "1244ae56900fcd6ce11207d8c4040176e4ba9fef3d563741a1027b229134cfe1" +
+ "c0a90d9c8eba9ce6349835e769024100e82494b6f777c784ffc29298d033e11d" +
+ "af46f0d464c4dbd950d46bcd697d0f0b49a77699f0111d408e8748f2b461ab8f" +
+ "210071c9c20d8ecee3ae229cb9c3954b024100c9a976f0011fcdc0ca7fb2f679" +
+ "974fa85d420c604ca7ff64fe4667a44f73088eef290d22195474039760e99325" +
+ "3ca45ee444588b150467d14451d3c45dab0ba5024019df39d3ca70c703c39d63" +
+ "c9342b1403c2ed1d1a0ec101df8e6a9e391e7099a4a068d187068261c8381a4b" +
+ "bf00eb81bb49ea4ac439a4592e25a1daa9acea67510241008c4640007497bdd4" +
+ "94473da26b33d06a29ecae9531dd4e2edf1cf42cfc42e53a1fac2b8183a3164c" +
+ "053999600c6fe15a4c682a3b1cb482ceb33a4416fc9ce52d024100e4f08cd10a" +
+ "5c8face0b20db86443d0a42e34dfdde236dae4f042a06dd3aff7ca159f8aa3b7" +
+ "854df41d510148096155204f2bf46c4a96e271747a4126a66ade6c"),
+
+ // This certificate is generated by the below commands:
+ // openssl dsaparam -genkey 1024 -out key.pem
+ // openssl req -x509 -new -key key.pem -days 7300 \
+ // -subj "/CN=DSA_SHA1_1024" -sha1 -out cert.pem
+ DSA_SHA1_1024(
+ SignatureAlgorithm.DSA,
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICuzCCAnugAwIBAgIJAMAMLRrhQWQFMAkGByqGSM44BAMwGDEWMBQGA1UEAwwN\n" +
+ "RFNBX1NIQTFfMTAyNDAeFw0xNzExMDIwNjA4MDRaFw0zNzEwMjgwNjA4MDRaMBgx\n" +
+ "FjAUBgNVBAMMDURTQV9TSEExXzEwMjQwggG2MIIBKwYHKoZIzjgEATCCAR4CgYEA\n" +
+ "8CspE1sE84pJ4YxzVHFEDNJvBaIxsbax03pDwNHr/ogP9PVwF9z1jT6hpC5WluHG\n" +
+ "g5n5gqpF2XpBhX2fKm1qqZWRxNvHKo0+zzAhUqMrvRJqcjlL4ijXndHldt67/VKS\n" +
+ "0eTKi9m64c+yJx80YYphCO5b93d2sTM29z8QZOlrbD8CFQCmttKnPAOk4uz8Z8cV\n" +
+ "uPGeGOMB9wKBgCItgPpAjW0srIwCaDysDNpydX6hB+1NTy1gFYl24n8edLGbR0mZ\n" +
+ "isteBd6LjMtgicRmtKZzKxW7igxoVvR3WHpTucFjms5NRNjPaj5wt3DxoXn4hyWk\n" +
+ "LzMvDeBvi+jKJiO0jnQ3+1NDOlAQy6ukeH59/gxZ3UmcNxDlAQ/IYHcpA4GEAAKB\n" +
+ "gEgvi72gL+zax7Y2hg4PL1PqZx2jFp0XlTIugiTrcsGytrAnn+/s2+3xVyVyvVMn\n" +
+ "0z5yL5eP9cdGA7qV1+7n6KJ8jNAhLCBSiC6x5ekd88aTlqnmt5lstk4w0Q0zSa58\n" +
+ "Hp6dCFg2Irk6Z9ERKaXJJBBS6reaFeATVROhN/LEEzzvo1AwTjAdBgNVHQ4EFgQU\n" +
+ "jb+HHABclGNR4lpf19nHFZpfwPQwHwYDVR0jBBgwFoAUjb+HHABclGNR4lpf19nH\n" +
+ "FZpfwPQwDAYDVR0TBAUwAwEB/zAJBgcqhkjOOAQDAy8AMCwCFDB3F/m6jsZdHaoy\n" +
+ "1xTp2U8uHBO+AhQYzeJuJd8/qRSDVLs8mesE8TQg2g==\n" +
+ "-----END CERTIFICATE-----",
+ "3082014a0201003082012b06072a8648ce3804013082011e02818100f02b2913" +
+ "5b04f38a49e18c735471440cd26f05a231b1b6b1d37a43c0d1ebfe880ff4f570" +
+ "17dcf58d3ea1a42e5696e1c68399f982aa45d97a41857d9f2a6d6aa99591c4db" +
+ "c72a8d3ecf302152a32bbd126a72394be228d79dd1e576debbfd5292d1e4ca8b" +
+ "d9bae1cfb2271f34618a6108ee5bf77776b13336f73f1064e96b6c3f021500a6" +
+ "b6d2a73c03a4e2ecfc67c715b8f19e18e301f7028180222d80fa408d6d2cac8c" +
+ "02683cac0cda72757ea107ed4d4f2d60158976e27f1e74b19b4749998acb5e05" +
+ "de8b8ccb6089c466b4a6732b15bb8a0c6856f477587a53b9c1639ace4d44d8cf" +
+ "6a3e70b770f1a179f88725a42f332f0de06f8be8ca2623b48e7437fb53433a50" +
+ "10cbaba4787e7dfe0c59dd499c3710e5010fc8607729041602146ef9db36045f" +
+ "bcd8c7fd82ba29c5c5057ed11c7f"),
+
+ // This certificate is generated by the below commands:
+ // openssl dsaparam -genkey 1024 -out key.pem
+ // openssl req -x509 -new -key key.pem -days 7300 \
+ // -subj "/CN=www.example.com" -sha1 -out cert.pem
+ DSA_EXAMPLE_SHA1_1024(
+ SignatureAlgorithm.DSA,
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICwDCCAoCgAwIBAgIJAI5mKbdK5ZqyMAkGByqGSM44BAMwGjEYMBYGA1UEAwwP\n" +
+ "d3d3LmV4YW1wbGUuY29tMB4XDTE3MTEwMjA1NDczOVoXDTM3MTAyODA1NDczOVow\n" +
+ "GjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIIBtzCCASwGByqGSM44BAEwggEf\n" +
+ "AoGBANVGWRSlxVZQKlVrTDcU/6Mr8QFlR3kGKmkvdbTHH1EhcP7YlZ7CJ30VBDbN\n" +
+ "LS2HvN3HHNooJ7hHBheL5Yz8EZIUa95TzPukZ1TmCo9fufR5i9HWj9Z8jLhyqx3l\n" +
+ "iUZOYN9H0MSn4ftK6dr5oTz2ZGYDblXDCq6R8qZfuw1URFqrAhUArx0nmGEI/1S/\n" +
+ "qyxnV4I6ItOntxMCgYEAxZKIZ/7aOGfzaQG2wRFdD/viHBZkkcxCsgmPUroQVUIw\n" +
+ "dqmUnfYk8cb02LCevhhSwcjfocQsA3y1jufIUdWaHuIB9W3EsFJQNd/Byh9j/pRD\n" +
+ "7zH/8lnBzJh2S7y10Vg840STVo5+ekZb4E+W7KK5gUaEQ6kAtUIIB0xjNz7RWs4D\n" +
+ "gYQAAoGAPVQKWqJSlMrbU4XEsx50Ur8P84CwMnS7WcQNLnih1ScaK2BijgVj5Fny\n" +
+ "9JZxITwj7XD7FWriq3kTjbydi3iAvrgVWij79x5Z7fTRCuoBVmtnAFkVGalwbGr2\n" +
+ "ghz70y6hep2Evb1pRCrHjRkMaJFE5Y2CA7VbpKoat+j47/LkXJ2jUDBOMB0GA1Ud\n" +
+ "DgQWBBSVjWy3SpaDfnFo+37mZJqX2aybzTAfBgNVHSMEGDAWgBSVjWy3SpaDfnFo\n" +
+ "+37mZJqX2aybzTAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUd5NOlcfX\n" +
+ "5rakT9H8UzlFcFQLr0MCFGrEYvlFUf/HJOH4FwXS2jEholBB\n" +
+ "-----END CERTIFICATE-----",
+ "3082014c0201003082012c06072a8648ce3804013082011f02818100d5465914" +
+ "a5c556502a556b4c3714ffa32bf101654779062a692f75b4c71f512170fed895" +
+ "9ec2277d150436cd2d2d87bcddc71cda2827b84706178be58cfc1192146bde53" +
+ "ccfba46754e60a8f5fb9f4798bd1d68fd67c8cb872ab1de589464e60df47d0c4" +
+ "a7e1fb4ae9daf9a13cf66466036e55c30aae91f2a65fbb0d54445aab021500af" +
+ "1d27986108ff54bfab2c6757823a22d3a7b71302818100c5928867feda3867f3" +
+ "6901b6c1115d0ffbe21c166491cc42b2098f52ba1055423076a9949df624f1c6" +
+ "f4d8b09ebe1852c1c8dfa1c42c037cb58ee7c851d59a1ee201f56dc4b0525035" +
+ "dfc1ca1f63fe9443ef31fff259c1cc98764bbcb5d1583ce34493568e7e7a465b" +
+ "e04f96eca2b981468443a900b54208074c63373ed15ace0417021500abf47692" +
+ "88c6ac41e2802e7eb7addba367339318"),
+
+ // This certificate is generated by the below commands:
+ // openssl ecparam -name prime256v1 -genkey -out key.pem
+ // openssl req -new -key key.pem -x509 -nodes -days 7300 \
+ // -subj "/CN=ECDSA_SHA1_prime256v1" -sha1 -out cert.pem
+ ECDSA_SHA1_PRIME256V1(
+ SignatureAlgorithm.ECDSA,
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIBhDCCASygAwIBAgIJAKW4wuujp9JbMAkGByqGSM49BAEwIDEeMBwGA1UEAwwV\n" +
+ "RUNEU0FfU0hBMV9wcmltZTI1NnYxMB4XDTE3MDkwNzAyMTA0MVoXDTM3MDkwMjAy\n" +
+ "MTA0MVowIDEeMBwGA1UEAwwVRUNEU0FfU0hBMV9wcmltZTI1NnYxMFkwEwYHKoZI\n" +
+ "zj0CAQYIKoZIzj0DAQcDQgAEdbE+AMwsFBf73YXRVwsvsx2dMt1xgDxj/4pN+BfY\n" +
+ "LWnO94beeZcrCJ1/N8CHmDOce7KRDR6/9kpi20wFAVXZ3KNQME4wHQYDVR0OBBYE\n" +
+ "FA/hB2ODDNdz1JF08u2uhknhlsVoMB8GA1UdIwQYMBaAFA/hB2ODDNdz1JF08u2u\n" +
+ "hknhlsVoMAwGA1UdEwQFMAMBAf8wCQYHKoZIzj0EAQNHADBEAiBNxv2L2FW+6+w/\n" +
+ "QtDe+YSUNRj3F8QrpLkfGk7rVaOiHQIgVF2pWJ5ytg0pbCuO8Bh+UZ7zfZUD03s8\n" +
+ "ZuIYW7RtMe0=\n" +
+ "-----END CERTIFICATE-----",
+ "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02" +
+ "010104204d901d5efd0e3def78d5307788a4c760115effce4b9e2c31ae5860b6" +
+ "c11915aca1440342000475b13e00cc2c1417fbdd85d1570b2fb31d9d32dd7180" +
+ "3c63ff8a4df817d82d69cef786de79972b089d7f37c08798339c7bb2910d1ebf" +
+ "f64a62db4c050155d9dc"),
+
+ // This certificate is generated by the below commands:
+ // openssl ecparam -name prime256v1 -genkey -out key.pem
+ // openssl req -new -key key.pem -x509 -nodes -days 7300 \
+ // -subj "/CN=www.example.com" -sha1 -out cert.pem
+ ECDSA_EXAMPLE_SHA1_PRIME256V1(
+ SignatureAlgorithm.ECDSA,
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIBeDCCASCgAwIBAgIJAMxOXBpiJ5mDMAkGByqGSM49BAEwGjEYMBYGA1UEAwwP\n" +
+ "d3d3LmV4YW1wbGUuY29tMB4XDTE3MTEwMjA1MTg0MVoXDTM3MTAyODA1MTg0MVow\n" +
+ "GjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" +
+ "AQcDQgAER9IyuwyrJ7X9DmIqGC3YNTlWBt4Fo/Y3RnlcxhTVxb/ZAYVNhqe4MbSM\n" +
+ "2nsVnYMjjXXDav1plNKvmgGDf9s/saNQME4wHQYDVR0OBBYEFHNUTaIIEA89uNKH\n" +
+ "OOUgJ981Qj5HMB8GA1UdIwQYMBaAFHNUTaIIEA89uNKHOOUgJ981Qj5HMAwGA1Ud\n" +
+ "EwQFMAMBAf8wCQYHKoZIzj0EAQNHADBEAiBCW59S1nE15j8euO6/q9bM6J9Ci5xJ\n" +
+ "WWAVznGGxnS/HgIgFaFKC31uxTXoBN7QN0yW/umQgJ0nsjwj7Pnxc0wNyw8=\n" +
+ "-----END CERTIFICATE-----",
+ "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02" +
+ "010104209aa3784cd0c1fe0553e59b3c7b8f08c8fdaffd94f34e2c1683243a79" +
+ "7b64b673a1440342000447d232bb0cab27b5fd0e622a182dd835395606de05a3" +
+ "f63746795cc614d5c5bfd901854d86a7b831b48cda7b159d83238d75c36afd69" +
+ "94d2af9a01837fdb3fb1");
+
+ public final SignatureAlgorithm signatureAlgorithm;
+ public final String certMaterials;
+ public final String privKeyMaterials;
+
+ private Cert(
+ SignatureAlgorithm signatureAlgorithm,
+ String certMaterials,
+ String privKeyMaterials) {
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.certMaterials = certMaterials;
+ this.privKeyMaterials = privKeyMaterials;
+ }
+
+ // Two certificates (mainCert and exampleCert) are selected to respect the
+ // specified cipher suite. SNI-associated cases specify exampleCert as desired.
+ public static Cert[] getCerts(String cipherSuite) {
+ Cert mainCert = Cert.DSA_SHA1_1024;
+ Cert exampleCert = Cert.DSA_EXAMPLE_SHA1_1024;
+ if (cipherSuite.contains("_ECDHE_RSA_")) {
+ mainCert = Cert.RSA_SHA1_1024;
+ exampleCert = Cert.RSA_EXAMPLE_SHA1_1024;
+ } else if (cipherSuite.contains("_EC")) {
+ mainCert = Cert.ECDSA_SHA1_PRIME256V1;
+ exampleCert = Cert.ECDSA_EXAMPLE_SHA1_PRIME256V1;
+ } else if (cipherSuite.contains("_RSA")) {
+ mainCert = Cert.RSA_SHA1_1024;
+ exampleCert = Cert.RSA_EXAMPLE_SHA1_1024;
+ }
+ System.out.printf("mainCert=%s, exampleCert=%s%n",
+ mainCert, exampleCert);
+ return new Cert[] { mainCert, exampleCert };
+ }
+}
+
+enum SignatureAlgorithm {
+
+ RSA, DSA, ECDSA;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/Client.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,206 @@
+/*
+ * 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.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+/*
+ * A simple SSL socket client.
+ */
+public class Client {
+
+ private final SSLSocket socket;
+
+ public Client(SSLContext context) throws Exception {
+ SSLSocketFactory socketFactory = context.getSocketFactory();
+ socket = (SSLSocket) socketFactory.createSocket();
+ socket.setSoTimeout(Utils.TIMEOUT);
+ }
+
+ public Client(Cert... certs) throws Exception {
+ this(Utils.createSSLContext(certs));
+ }
+
+ private SSLSession getSession() {
+ return socket.getSession();
+ }
+
+ private void setEnabledCipherSuites(String... cipherSuites) {
+ socket.setEnabledCipherSuites(cipherSuites);
+ }
+
+ private void setEnabledProtocols(String... protocols) {
+ socket.setEnabledProtocols(protocols);
+ }
+
+ @SuppressWarnings(value = { "unchecked", "rawtypes" })
+ private void setServerName(String hostname) {
+ List serverNames = new ArrayList();
+ serverNames.add(createSNIHostName(hostname));
+ SSLParameters params = socket.getSSLParameters();
+ params.setServerNames(serverNames);
+ socket.setSSLParameters(params);
+ }
+
+ // Create SNIHostName via reflection due to pre-8 JDK builds don't support
+ // SNI. Those JDK builds cannot find classes SNIServerName and SNIHostName.
+ private Object createSNIHostName(String hostname) {
+ try {
+ Class<?> clazz = Class.forName("javax.net.ssl.SNIHostName");
+ return clazz.getConstructor(String.class).newInstance(hostname);
+ } catch (Exception e) {
+ throw new RuntimeException("Creates SNIHostName failed!", e);
+ }
+ }
+
+ private void setApplicationProtocols(String... protocols) {
+ SSLParameters params = socket.getSSLParameters();
+ params.setApplicationProtocols(protocols);
+ socket.setSSLParameters(params);
+ }
+
+ private String getNegotiatedApplicationProtocol() {
+ return socket.getApplicationProtocol();
+ }
+
+ private void oneTimeConnect(String host, int port) throws IOException {
+ socket.connect(new InetSocketAddress(host, port));
+
+ OutputStream out = socket.getOutputStream();
+ out.write('C');
+ out.flush();
+
+ InputStream in = socket.getInputStream();
+ in.read();
+ }
+
+ public void close() throws IOException {
+ socket.close();
+ }
+
+ public static void main(String[] args) throws IOException {
+ System.out.println("----- Client start -----");
+ int port = Integer.valueOf(System.getProperty(Utils.PROP_PORT));
+
+ String protocol = System.getProperty(Utils.PROP_PROTOCOL);
+ String cipherSuite = System.getProperty(Utils.PROP_CIPHER_SUITE);
+ String serverName = System.getProperty(Utils.PROP_SERVER_NAME);
+ String appProtocols = System.getProperty(Utils.PROP_APP_PROTOCOLS);
+ boolean supportsSNIOnServer
+ = Utils.getBoolProperty(Utils.PROP_SUPPORTS_SNI_ON_SERVER);
+ boolean supportsSNIOnClient
+ = Utils.getBoolProperty(Utils.PROP_SUPPORTS_SNI_ON_CLIENT);
+ boolean supportsALPNOnServer
+ = Utils.getBoolProperty(Utils.PROP_SUPPORTS_ALPN_ON_SERVER);
+ boolean supportsALPNOnClient
+ = Utils.getBoolProperty(Utils.PROP_SUPPORTS_ALPN_ON_CLIENT);
+ boolean negativeCase
+ = Utils.getBoolProperty(Utils.PROP_NEGATIVE_CASE_ON_CLIENT);
+ System.out.println(Utils.join(Utils.PARAM_DELIMITER,
+ "ClientJDK=" + System.getProperty(Utils.PROP_CLIENT_JDK),
+ "Protocol=" + protocol,
+ "CipherSuite=" + cipherSuite,
+ "ServerName=" + serverName,
+ "AppProtocols=" + appProtocols));
+
+ Status status = Status.SUCCESS;
+ Client client = null;
+ try {
+ client = new Client(Cert.getCerts(cipherSuite));
+ client.setEnabledProtocols(protocol);
+ client.setEnabledCipherSuites(cipherSuite);
+
+ if (serverName != null) {
+ if (supportsSNIOnClient) {
+ client.setServerName(serverName);
+ } else {
+ System.out.println(
+ "Ignored due to client doesn't support SNI.");
+ }
+ }
+
+ if (appProtocols != null) {
+ if (supportsALPNOnClient) {
+ client.setApplicationProtocols(
+ Utils.split(appProtocols, Utils.VALUE_DELIMITER));
+ } else {
+ System.out.println(
+ "Ignored due to client doesn't support ALPN.");
+ }
+ }
+
+ client.oneTimeConnect("localhost", port);
+
+ if (serverName != null && supportsSNIOnServer
+ && supportsSNIOnClient) {
+ X509Certificate cert
+ = (X509Certificate) client.getSession().getPeerCertificates()[0];
+ String subject
+ = cert.getSubjectX500Principal().getName();
+ if (!subject.contains(serverName)) {
+ System.out.println("Unexpected server: " + subject);
+ status = Status.FAIL;
+ }
+ }
+
+ if (appProtocols != null && supportsALPNOnServer
+ && supportsALPNOnClient) {
+ String negoAppProtocol
+ = client.getNegotiatedApplicationProtocol();
+ String expectedNegoAppProtocol
+ = System.getProperty(Utils.PROP_NEGO_APP_PROTOCOL);
+ if (!expectedNegoAppProtocol.equals(negoAppProtocol)) {
+ System.out.println("Unexpected negotiated app protocol: "
+ + negoAppProtocol);
+ status = Status.FAIL;
+ }
+ }
+
+ if (status != Status.FAIL) {
+ status = negativeCase
+ ? Status.UNEXPECTED_SUCCESS
+ : Status.SUCCESS;
+ }
+ } catch (Exception exception) {
+ status = Utils.handleException(exception, negativeCase);
+ } finally {
+ if (client != null) {
+ client.close();
+ }
+ }
+
+ System.out.println("STATUS: " + status);
+ System.out.println("----- Client end -----");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/Compatibility.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,338 @@
+/*
+ * 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
+ * @summary This test is used to check the interop compatibility on JSSE among
+ * different JDK releases.
+ * Note that, this is a manual test. For more details about the test and
+ * its usages, please look through README.
+ *
+ * @library /test/lib
+ * @compile -source 1.6 -target 1.6 JdkUtils.java Parameter.java Server.java Client.java
+ * @run main/manual Compatibility
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class Compatibility {
+
+ public static void main(String[] args) throws Throwable {
+ String javaSecurityFile
+ = System.getProperty("test.src") + "/java.security";
+ boolean debug = Utils.getBoolProperty("debug");
+
+ Set<JdkInfo> jdkInfos = jdkInfoList();
+
+ System.out.println("Test start");
+
+ List<TestCase> testCases = new ArrayList<>();
+ ExecutorService executor = Executors.newCachedThreadPool();
+ PrintStream origStdOut = System.out;
+ PrintStream origStdErr = System.err;
+
+ try (PrintStream printStream = new PrintStream(
+ new FileOutputStream(Utils.TEST_LOG, true))) {
+ System.setOut(printStream);
+ System.setErr(printStream);
+
+ System.out.println(Utils.startHtml());
+ System.out.println(Utils.startPre());
+
+ for (UseCase useCase : UseCase.getAllUseCases()) {
+ for (JdkInfo serverJdk : jdkInfos) {
+ if (useCase.ignoredByJdk(serverJdk)) {
+ continue;
+ }
+
+ Map<String, String> props = new LinkedHashMap<>();
+ if (debug) {
+ props.put("javax.net.debug", "ssl");
+ }
+ props.put("java.security.properties", javaSecurityFile);
+
+ props.put(Utils.PROP_PROTOCOL, useCase.protocol.version);
+ props.put(Utils.PROP_CIPHER_SUITE, useCase.cipherSuite.name());
+ props.put(Utils.PROP_CLIENT_AUTH, useCase.clientAuth.name());
+ if (useCase.appProtocol != AppProtocol.NONE) {
+ props.put(Utils.PROP_APP_PROTOCOLS,
+ Utils.join(Utils.VALUE_DELIMITER,
+ useCase.appProtocol.appProtocols));
+ props.put(Utils.PROP_NEGO_APP_PROTOCOL,
+ useCase.appProtocol.negoAppProtocol);
+ }
+ props.put(Utils.PROP_SERVER_JDK, serverJdk.version);
+
+ props.put(Utils.PROP_SUPPORTS_SNI_ON_SERVER,
+ serverJdk.supportsSNI + "");
+ props.put(Utils.PROP_SUPPORTS_ALPN_ON_SERVER,
+ serverJdk.supportsALPN + "");
+
+ for (JdkInfo clientJdk : jdkInfos) {
+ if (useCase.ignoredByJdk(clientJdk)) {
+ continue;
+ }
+
+ TestCase testCase = new TestCase(serverJdk, clientJdk,
+ useCase);
+ System.out.println(Utils.anchorName(testCase.toString(),
+ "----- Case start -----"));
+ System.out.println(testCase.toString());
+
+ props.put(Utils.PROP_NEGATIVE_CASE_ON_SERVER,
+ testCase.negativeCaseOnServer + "");
+ props.put(Utils.PROP_NEGATIVE_CASE_ON_CLIENT,
+ testCase.negativeCaseOnClient + "");
+
+ Future<OutputAnalyzer> serverFuture = executor.submit(() -> {
+ return runServer(serverJdk.jdkPath, props);
+ });
+ int port = waitForServerStarted();
+ System.out.println("port=" + port);
+
+ props.put(Utils.PROP_PORT, port + "");
+
+ props.put(Utils.PROP_CLIENT_JDK, clientJdk.version);
+
+ props.put(Utils.PROP_SUPPORTS_SNI_ON_CLIENT,
+ clientJdk.supportsSNI + "");
+ props.put(Utils.PROP_SUPPORTS_ALPN_ON_CLIENT,
+ clientJdk.supportsALPN + "");
+ if (useCase.serverName != ServerName.NONE) {
+ props.put(Utils.PROP_SERVER_NAME,
+ useCase.serverName.name);
+ }
+
+ Status clientStatus = null;
+ if (port != -1) {
+ String clientOutput = runClient(clientJdk.jdkPath,
+ props).getOutput();
+ clientStatus = getStatus(clientOutput);
+ }
+
+ String serverOutput = serverFuture.get().getOutput();
+ Status serverStatus = getStatus(serverOutput);
+ testCase.setStatus(caseStatus(serverStatus, clientStatus));
+ testCases.add(testCase);
+ System.out.printf(
+ "ServerStatus=%s, ClientStatus=%s, CaseStatus=%s%n",
+ serverStatus, clientStatus, testCase.getStatus());
+
+ // Confirm the server has stopped.
+ if(new File(Utils.PORT_LOG).exists()) {
+ throw new RuntimeException("Server doesn't stop.");
+ }
+ System.out.println("----- Case end -----");
+ }
+ }
+ }
+
+ System.out.println(Utils.endPre());
+ System.out.println(Utils.endHtml());
+ }
+ System.setOut(origStdOut);
+ System.setErr(origStdErr);
+ executor.shutdown();
+
+ System.out.println("Test end");
+ System.out.println("Report is being generated...");
+ boolean failed = generateReport(testCases);
+ System.out.println("Report is generated.");
+ if (failed) {
+ throw new RuntimeException("At least one case failed. "
+ + "Please check logs for more details.");
+ }
+ }
+
+ private static Status getStatus(String log) {
+ if (log.contains(Status.UNEXPECTED_SUCCESS.name())) {
+ return Status.UNEXPECTED_SUCCESS;
+ } else if (log.contains(Status.SUCCESS.name())) {
+ return Status.SUCCESS;
+ } else if (log.contains(Status.EXPECTED_FAIL.name())) {
+ return Status.EXPECTED_FAIL;
+ } else if (log.contains(Status.TIMEOUT.name())) {
+ return Status.TIMEOUT;
+ } else {
+ return Status.FAIL;
+ }
+ }
+
+ private static Status caseStatus(Status serverStatus, Status clientStatus) {
+ if (clientStatus == null || clientStatus == Status.TIMEOUT) {
+ return serverStatus == Status.EXPECTED_FAIL
+ ? Status.EXPECTED_FAIL
+ : Status.FAIL;
+ } else if (serverStatus == Status.TIMEOUT) {
+ return clientStatus == Status.EXPECTED_FAIL
+ ? Status.EXPECTED_FAIL
+ : Status.FAIL;
+ } else {
+ return serverStatus == clientStatus
+ ? serverStatus
+ : Status.FAIL;
+ }
+ }
+
+ // Retrieves JDK info from the file which is specified by jdkListFile.
+ // If no such file or no JDK is specified by the file, the current testing
+ // JDK will be used.
+ private static Set<JdkInfo> jdkInfoList() throws Throwable {
+ List<String> jdkList = jdkList("jdkListFile");
+ if (jdkList.size() == 0) {
+ jdkList.add(System.getProperty("test.jdk"));
+ }
+
+ Set<JdkInfo> jdkInfoList = new LinkedHashSet<>();
+ for (String jdkPath : jdkList) {
+ JdkInfo jdkInfo = new JdkInfo(jdkPath);
+ // JDK version must be unique.
+ if (!jdkInfoList.add(jdkInfo)) {
+ System.out.println("The JDK version is duplicate: " + jdkPath);
+ }
+ }
+ return jdkInfoList;
+ }
+
+ private static List<String> jdkList(String listFileProp) throws IOException {
+ String listFile = System.getProperty(listFileProp);
+ System.out.println(listFileProp + "=" + listFile);
+ if (listFile != null && new File(listFile).exists()) {
+ return Files.lines(Paths.get(listFile))
+ .filter(line -> { return !line.trim().isEmpty(); })
+ .collect(Collectors.toList());
+ } else {
+ return new ArrayList<>();
+ }
+ }
+
+ // Checks if server is already launched, and returns server port.
+ private static int waitForServerStarted()
+ throws IOException, InterruptedException {
+ System.out.print("Waiting for server");
+ long deadline = System.currentTimeMillis() + Utils.TIMEOUT;
+ int port;
+ while ((port = getServerPort()) == -1
+ && System.currentTimeMillis() < deadline) {
+ System.out.print(".");
+ TimeUnit.SECONDS.sleep(1);
+ }
+ System.out.println();
+
+ return port;
+ }
+
+ // Retrieves the latest server port from port.log.
+ private static int getServerPort() throws IOException {
+ if (!new File(Utils.PORT_LOG).exists()) {
+ return -1;
+ }
+
+ return Integer.valueOf(
+ Files.lines(Paths.get(Utils.PORT_LOG)).findFirst().get());
+ }
+
+ private static OutputAnalyzer runServer(String jdkPath,
+ Map<String, String> props) {
+ return ProcessUtils.java(jdkPath, props, Server.class);
+ }
+
+ private static OutputAnalyzer runClient(String jdkPath,
+ Map<String, String> props) {
+ return ProcessUtils.java(jdkPath, props, Client.class);
+ }
+
+ // Generates the test result report.
+ private static boolean generateReport(List<TestCase> testCases)
+ throws IOException {
+ boolean failed = false;
+ StringBuilder report = new StringBuilder();
+ report.append(Utils.startHtml());
+ report.append(Utils.tableStyle());
+ report.append(Utils.startTable());
+ report.append(Utils.row(
+ "No.",
+ "ServerJDK",
+ "ClientJDK",
+ "Protocol",
+ "CipherSuite",
+ "ClientAuth",
+ "SNI",
+ "ALPN",
+ "Status"));
+ for (int i = 0, size = testCases.size(); i < size; i++) {
+ TestCase testCase = testCases.get(i);
+
+ report.append(Utils.row(
+ Utils.anchorLink(
+ Utils.TEST_LOG,
+ testCase.toString(),
+ i + ""),
+ testCase.serverJdk.version,
+ testCase.clientJdk.version,
+ testCase.useCase.protocol.version,
+ testCase.useCase.cipherSuite,
+ Utils.boolToStr(
+ testCase.useCase.clientAuth == ClientAuth.TRUE),
+ Utils.boolToStr(
+ testCase.useCase.serverName == ServerName.EXAMPLE),
+ Utils.boolToStr(
+ testCase.useCase.appProtocol == AppProtocol.EXAMPLE),
+ testCase.getStatus()));
+ failed = failed
+ || testCase.getStatus() == Status.FAIL
+ || testCase.getStatus() == Status.UNEXPECTED_SUCCESS;
+ }
+ report.append(Utils.endTable());
+ report.append(Utils.endHtml());
+
+ generateFile("report.html", report.toString());
+ return failed;
+ }
+
+ private static void generateFile(String path, String content)
+ throws IOException {
+ try(FileWriter writer = new FileWriter(new File(path))) {
+ writer.write(content);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/JdkInfo.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+/*
+ * It represents a JDK with some specific attributes.
+ * If two JdkInfo instances have the same version value, the instances are
+ * regarded as equivalent.
+ */
+public class JdkInfo {
+
+ public final String jdkPath;
+
+ public final String version;
+ public final boolean supportsECKey;
+ public final boolean supportsSNI;
+ public final boolean supportsALPN;
+
+ public JdkInfo(String jdkPath) throws Throwable {
+ this.jdkPath = jdkPath;
+
+ String output = jdkAttributes(jdkPath);
+ if (output == null || output.trim().isEmpty()) {
+ throw new RuntimeException(
+ "Cannot determine the JDK attributes: " + jdkPath);
+ }
+
+ String[] attributes = Utils.split(output, Utils.PARAM_DELIMITER);
+ version = attributes[0].replaceAll(".*=", "");
+ supportsECKey = Boolean.valueOf(attributes[1].replaceAll(".*=", ""));
+ supportsSNI = Boolean.valueOf(attributes[2].replaceAll(".*=", ""));
+ supportsALPN = Boolean.valueOf(attributes[3].replaceAll(".*=", ""));
+ }
+
+ // Determines the specific attributes for the specified JDK.
+ private static String jdkAttributes(String jdkPath) throws Throwable {
+ return ProcessUtils.java(jdkPath, null, JdkUtils.class).getOutput();
+ }
+
+ @Override
+ public int hashCode() {
+ return version == null ? 0 : version.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ JdkInfo other = (JdkInfo) obj;
+ if (version == null) {
+ if (other.version != null) {
+ return false;
+ }
+ } else if (!version.equals(other.version)) {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean supportsCipherSuite(CipherSuite cipherSuite) {
+ JdkRelease jdkRelease = JdkRelease.getRelease(version);
+ return cipherSuite.startJdk.sequence <= jdkRelease.sequence
+ && (cipherSuite.endJdk == null
+ || cipherSuite.endJdk.sequence >= jdkRelease.sequence);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/JdkRelease.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/*
+ * JDK major versions.
+ */
+public enum JdkRelease {
+
+ JDK6(6, "1.6"),
+ JDK7(7, "1.7"),
+ JDK8(8, "1.8"),
+ JDK9(9, "9"),
+ JDK10(10, "10");
+
+ public final int sequence;
+ public final String release;
+
+ private JdkRelease(int sequence, String release) {
+ this.sequence = sequence;
+ this.release = release;
+ }
+
+ public static JdkRelease getRelease(String jdkVersion) {
+ if (jdkVersion.startsWith(JDK6.release)) {
+ return JDK6;
+ } else if (jdkVersion.startsWith(JDK7.release)) {
+ return JDK7;
+ } else if (jdkVersion.startsWith(JDK8.release)) {
+ return JDK8;
+ } else if (jdkVersion.startsWith(JDK9.release)) {
+ return JDK9;
+ } else if (jdkVersion.startsWith(JDK10.release)) {
+ return JDK10;
+ }
+
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/JdkUtils.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,88 @@
+/*
+ * 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.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+
+import javax.net.ssl.SSLParameters;
+
+/*
+ * This class is used for returning some specific JDK information.
+ */
+public class JdkUtils {
+
+ public static final String JAVA_RUNTIME_VERSION = "javaRuntimeVersion";
+ public static final String SUPPORTS_EC_KEY = "supportsECKey";
+ public static final String SUPPORTS_SNI = "supportsSNI";
+ public static final String SUPPORTS_ALPN = "supportsALPN";
+
+ // Returns the JDK build version.
+ public static String javaRuntimeVersion() {
+ return System.getProperty("java.runtime.version");
+ }
+
+ // Checks if EC key algorithm is supported by the JDK build.
+ private static boolean supportsECKey() {
+ boolean isSupported = true;
+ try {
+ KeyFactory.getInstance("EC");
+ } catch (NoSuchAlgorithmException e) {
+ isSupported = false;
+ }
+ return isSupported;
+ }
+
+ // Checks if SNI is supported by the JDK build.
+ private static boolean supportsSNI() {
+ boolean isSupported = true;
+ try {
+ SSLParameters.class.getMethod("getServerNames");
+ } catch (NoSuchMethodException e) {
+ isSupported = false;
+ }
+ return isSupported;
+ }
+
+ // Checks if ALPN is supported by the JDK build.
+ private static boolean supportsALPN() {
+ boolean isSupported = true;
+ try {
+ SSLParameters.class.getMethod("getApplicationProtocols");
+ } catch (NoSuchMethodException e) {
+ isSupported = false;
+ }
+ return isSupported;
+ }
+
+ public static void main(String[] args) {
+ System.out.print(Utils.join(Utils.PARAM_DELIMITER,
+ attr(JAVA_RUNTIME_VERSION, javaRuntimeVersion()),
+ attr(SUPPORTS_EC_KEY, supportsECKey()),
+ attr(SUPPORTS_SNI, supportsSNI()),
+ attr(SUPPORTS_ALPN, supportsALPN())));
+ }
+
+ private static String attr(String name, Object value) {
+ return name + "=" + String.valueOf(value);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/Parameter.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,252 @@
+/*
+ * 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.
+ */
+
+/*
+ * A tagging interface that all TLS communication parameters must implement.
+ */
+public interface Parameter { }
+
+/* The followings are TLS communication parameters. */
+
+enum Protocol implements Parameter {
+
+ SSLV3_0(3, "SSLv3"),
+ TLSV1_0(4, "TLSv1"),
+ TLSV1_1(5, "TLSv1.1"),
+ TLSV1_2(6, "TLSv1.2");
+
+ public final int sequence;
+ public final String version;
+
+ private Protocol(int sequence, String version) {
+ this.sequence = sequence;
+ this.version = version;
+ }
+
+ static Protocol getProtocol(String version) {
+ for (Protocol protocol : values()) {
+ if (protocol.version.equals(version)) {
+ return protocol;
+ }
+ }
+
+ return null;
+ }
+
+ static Protocol[] getMandatoryValues() {
+ return new Protocol[] { TLSV1_0, TLSV1_1, TLSV1_2 };
+ }
+}
+
+enum CipherSuite implements Parameter {
+
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_RSA_WITH_AES_256_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(),
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(),
+ TLS_RSA_WITH_AES_256_CBC_SHA(),
+ TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA(),
+ TLS_ECDH_RSA_WITH_AES_256_CBC_SHA(),
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA(),
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA(),
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_RSA_WITH_AES_128_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK7),
+ 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(
+ Protocol.SSLV3_0, JdkRelease.JDK7),
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA(),
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA(),
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_RSA_WITH_AES_256_GCM_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_DHE_DSS_WITH_AES_256_GCM_SHA384(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_RSA_WITH_AES_128_GCM_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_DHE_DSS_WITH_AES_128_GCM_SHA256(
+ Protocol.TLSV1_2, JdkRelease.JDK8),
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA(),
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA(),
+ TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA(),
+ TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA(),
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA(),
+ TLS_ECDHE_RSA_WITH_RC4_128_SHA(),
+ TLS_ECDH_ECDSA_WITH_RC4_128_SHA(),
+ TLS_ECDH_RSA_WITH_RC4_128_SHA(),
+ SSL_RSA_WITH_RC4_128_SHA(),
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA(),
+ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA(
+ Protocol.SSLV3_0, JdkRelease.JDK6),
+ SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA(
+ Protocol.SSLV3_0, JdkRelease.JDK6),
+ SSL_RSA_WITH_RC4_128_MD5(
+ Protocol.SSLV3_0, JdkRelease.JDK6);
+
+ private static final boolean FULL_CIPHER_SUITES
+ = Utils.getBoolProperty("fullCipherSuites");
+
+ final Protocol startProtocol;
+ final Protocol endProtocol;
+
+ final JdkRelease startJdk;
+ final JdkRelease endJdk;
+
+ private CipherSuite(
+ Protocol startProtocol, Protocol endProtocol,
+ JdkRelease startJdk, JdkRelease endJdk) {
+ this.startProtocol = startProtocol;
+ this.endProtocol = endProtocol;
+
+ this.startJdk = startJdk;
+ this.endJdk = endJdk;
+ }
+
+ private CipherSuite(Protocol startProtocol, JdkRelease startJdk) {
+ this(startProtocol, null, startJdk, null);
+ }
+
+ private CipherSuite() {
+ this(Protocol.TLSV1_0, null, JdkRelease.JDK6, null);
+ }
+
+ boolean supportedByProtocol(Protocol protocol) {
+ return startProtocol.sequence <= protocol.sequence
+ && (endProtocol == null || endProtocol.sequence >= protocol.sequence);
+ }
+
+ static CipherSuite[] getMandatoryValues() {
+ return FULL_CIPHER_SUITES
+ ? values()
+ : new CipherSuite[] {
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 };
+ }
+
+ static CipherSuite getCipherSuite(String name) {
+ for (CipherSuite cipherSuite : values()) {
+ if (cipherSuite.name().equals(name)) {
+ return cipherSuite;
+ }
+ }
+
+ return null;
+ }
+}
+
+enum ClientAuth implements Parameter {
+
+ FALSE,
+ TRUE;
+
+ static ClientAuth[] getMandatoryValues() {
+ return new ClientAuth[] { TRUE };
+ }
+}
+
+enum ServerName implements Parameter {
+
+ NONE(null),
+ EXAMPLE("www.example.com");
+
+ final String name;
+
+ private ServerName(String name) {
+ this.name = name;
+ }
+
+ static ServerName[] getMandatoryValues() {
+ return new ServerName[] { EXAMPLE };
+ }
+}
+
+enum AppProtocol implements Parameter {
+
+ NONE(null, null),
+ EXAMPLE(new String[] { Utils.HTTP_2, Utils.HTTP_1_1 }, Utils.HTTP_2);
+
+ final String[] appProtocols;
+
+ // Expected negotiated application protocol
+ final String negoAppProtocol;
+
+ private AppProtocol(String[] appProtocols, String negoAppProtocol) {
+ this.appProtocols = appProtocols;
+ this.negoAppProtocol = negoAppProtocol;
+ }
+
+ static AppProtocol[] getMandatoryValues() {
+ return new AppProtocol[] { EXAMPLE };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/ProcessUtils.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,59 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/*
+ * Utilities for executing java process.
+ */
+public class ProcessUtils {
+
+ private static final String TEST_CLASSES = System.getProperty("test.classes");
+
+ public static OutputAnalyzer java(String jdkPath, Map<String, String> props,
+ Class<?> clazz) {
+ List<String> cmds = new ArrayList<>();
+ cmds.add(jdkPath + "/bin/java");
+
+ if (props != null) {
+ for (Map.Entry<String, String> prop : props.entrySet()) {
+ cmds.add("-D" + prop.getKey() + "=" + prop.getValue());
+ }
+ }
+
+ cmds.add("-cp");
+ cmds.add(TEST_CLASSES);
+ cmds.add(clazz.getName());
+ try {
+ return ProcessTools.executeCommand(
+ cmds.toArray(new String[cmds.size()]));
+ } catch (Throwable e) {
+ throw new RuntimeException("Execute command failed: " + cmds, e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/README Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,130 @@
+# 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.
+
+##### Summary #####
+This test is used to check the interop compatibility on JSSE among different
+JDK releases. The oldest version supported by the test is JDK 6. Some of Java
+source files, JdkUtils.java, Parameter.java, Server.java, and Client.java, use
+only JDK 6-compliant language features and APIs, in order to allowing different
+JDK releases can load and run associated classes.
+
+##### Output #####
+The test can generate a report at $JTREG_WORKDIR/scratch/report.html to display
+the key information for each case. It also outputs all of details on both of
+server and client sides to a separated file at $JTREG_WORKDIR/scratch/test.html.
+
+##### Report Columns #####
+No.
+ A sequence number. It contains a hyper link to the corresponding details
+ in $JTREG_WORKDIR/scratch/test.html.
+
+ServerJDK
+ The version of the JDK that acts as server.
+
+ClientJDK
+ The version of the JDK that acts as client.
+
+Protocol
+ The TLS protocol version.
+
+CipherSuite
+ The only enabled cipher suite on both of server and client.
+
+ClientAuth
+ If the client authentication is checked, the value is "Y"; otherwise, "N".
+
+SNI
+ If the SNI is checked, the value is "Y"; otherwise, "N".
+
+ALPN
+ If the ALPN is checked, the value is "Y"; otherwise, "N".
+
+Status
+ It indicates the communication status for a test case.
+ There are three status:
+ SUCCESS: Communication succeed as expected.
+ UNEXPECTED_SUCCESS: Communication succeed as unexpected.
+ FAIL: Communication fails with unexpected failure.
+ EXPECTED_FAIL: Communication fails with expected failure.
+ Please note that, if a case finishes as status UNEXPECTED_SUCCESS or FAIL,
+ that means the case fails. Any failed case results in the test goes to fail.
+
+##### Usage #####
+jtreg [-options] \
+ [-Ddebug=<true|false>] \
+ [-DfullCases=<true|false>] \
+ [-DfullCipherSuites=<true|false>] \
+ [-DjdkListFile=</path/to/jdkListFile>] \
+ $JDK_WORKSPACE/test/jdk/javax/net/ssl/compatibility/Compatibility.java
+
+Besides the common jtreg options, like -jdk, this test introduces some more
+properties:
+debug
+ It indicates if the test enable -Djavax.net.ssl=debug. This is a boolean
+ property, and the default value is false.
+ It is not mandatory.
+
+fullCases
+ It indicates if testing the full or mandatory set of parameter values.
+ Every parameter provides a mandatory value set that must be covered.
+ For more details about the parameter value sets, please see Parameter.java.
+ This is a boolean property, and the default value is false.
+ It is not mandatory.
+
+fullCipherSuites
+ It indicates if testing the full or mandatory set of cipher suites.
+ For more details about the specific cipher suite sets, see CipherSuite in
+ Parameter.java.
+ This is a boolean property, and the default value is false.
+ It is not mandatory.
+
+jdkListFile
+ It indicate the path of a file, which lists the absolute paths of different
+ JDK builds. If no this property, the current testing JDK, specified by JTREG
+ option -jdk, is used as the testing JDK.
+ It is not mandatory.
+
+##### Usage Examples #####
+Example 1
+$ jtreg -jdk:/path/to/latest/jdk \
+ $JDK_WS/jdk/test/javax/net/ssl/compatibility/Compatibility.java
+This example doesn't specify any property introduced by the test. That means
+it uses the current testing JDK, namely /path/to/latest/jdk, as server and
+client. It doesn't output any debug log, and tests only mandatory parameter
+value sets.
+
+Example 2
+$ cat /path/to/jdkList
+/path/to/jdk6
+/path/to/jdk7
+/path/to/jdk8
+/path/to/jdk9
+/path/to/jdk10
+
+$ jtreg -jdk:/path/to/latest/jdk \
+ -Ddebug=true \
+ -DfullCipherSuites=true \
+ -DjdkListFile=/path/to/jdkList \
+ $JDK_WS/jdk/test/javax/net/ssl/compatibility/Compatibility.java
+The above example uses a file "/path/to/jdkList" to contain the paths of local
+different JDK builds through 6 to 10. The execution uses each of JDK builds as
+server and client respectively. And it enables SSL debug flag, and tests the
+full parameter value set.
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/Server.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,171 @@
+/*
+ * 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.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+
+/*
+ * A simple SSL socket server.
+ */
+public class Server {
+
+ private final SSLServerSocket serverSocket;
+
+ public Server(SSLContext context, int port) throws Exception {
+ SSLServerSocketFactory serverFactory = context.getServerSocketFactory();
+ serverSocket = (SSLServerSocket) serverFactory.createServerSocket(port);
+ serverSocket.setSoTimeout(Utils.TIMEOUT);
+ }
+
+ public Server(Cert[] certs, int port) throws Exception {
+ this(Utils.createSSLContext(certs), port);
+ }
+
+ public Server(Cert[] certs) throws Exception {
+ this(certs, 0);
+ }
+
+ private void setEnabledCipherSuites(String... cipherSuites) {
+ serverSocket.setEnabledCipherSuites(cipherSuites);
+ }
+
+ private void setEnabledProtocols(String... protocols) {
+ serverSocket.setEnabledProtocols(protocols);
+ }
+
+ private void setNeedClientAuth(boolean needClientAuth) {
+ serverSocket.setNeedClientAuth(needClientAuth);
+ }
+
+ private void setApplicationProtocols(String... protocols) {
+ SSLParameters params = serverSocket.getSSLParameters();
+ params.setApplicationProtocols(protocols);
+ serverSocket.setSSLParameters(params);
+ }
+
+ public int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ private void accept() throws IOException {
+ SSLSocket socket = null;
+ try {
+ socket = (SSLSocket) serverSocket.accept();
+
+ InputStream in = socket.getInputStream();
+ in.read();
+
+ OutputStream out = socket.getOutputStream();
+ out.write('S');
+ out.flush();
+ } finally {
+ if (socket != null) {
+ socket.close();
+ }
+ }
+ }
+
+ public void close() throws IOException {
+ serverSocket.close();
+ }
+
+ public static void main(String[] args) throws IOException {
+ System.out.println("----- Server start -----");
+ String protocol = System.getProperty(Utils.PROP_PROTOCOL);
+ String cipherSuite = System.getProperty(Utils.PROP_CIPHER_SUITE);
+ boolean clientAuth
+ = Utils.getBoolProperty(Utils.PROP_CLIENT_AUTH);
+ String appProtocols = System.getProperty(Utils.PROP_APP_PROTOCOLS);
+ boolean supportsALPN
+ = Utils.getBoolProperty(Utils.PROP_SUPPORTS_ALPN_ON_SERVER);
+ boolean negativeCase
+ = Utils.getBoolProperty(Utils.PROP_NEGATIVE_CASE_ON_SERVER);
+
+ System.out.println(Utils.join(Utils.PARAM_DELIMITER,
+ "ServerJDK=" + System.getProperty(Utils.PROP_SERVER_JDK),
+ "Protocol=" + protocol,
+ "CipherSuite=" + cipherSuite,
+ "ClientAuth=" + clientAuth,
+ "AppProtocols=" + appProtocols));
+
+ Status status = Status.SUCCESS;
+ Server server = null;
+ try {
+ server = new Server(Cert.getCerts(cipherSuite));
+ System.out.println("port=" + server.getPort());
+ server.setNeedClientAuth(clientAuth);
+ server.setEnabledProtocols(protocol);
+ server.setEnabledCipherSuites(cipherSuite);
+ if (appProtocols != null) {
+ if (supportsALPN) {
+ server.setApplicationProtocols(
+ Utils.split(appProtocols, Utils.VALUE_DELIMITER));
+ } else {
+ System.out.println(
+ "Ignored due to server doesn't support ALPN.");
+ }
+ }
+
+ savePort(server.getPort());
+ server.accept();
+
+ status = negativeCase ? Status.UNEXPECTED_SUCCESS : Status.SUCCESS;
+ } catch (Exception exception) {
+ status = Utils.handleException(exception, negativeCase);
+ } finally {
+ if (server != null) {
+ server.close();
+ }
+
+ // Cleanups port.log.
+ File file = new File(Utils.PORT_LOG);
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+
+ System.out.println("STATUS: " + status);
+ System.out.println("----- Server end -----");
+ }
+
+ private static void savePort(int port) throws IOException {
+ FileWriter writer = null;
+ try {
+ writer = new FileWriter(new File(Utils.PORT_LOG));
+ writer.write(port + "");
+ } finally {
+ if (writer != null) {
+ writer.close();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/Status.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,30 @@
+/*
+ * 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 case result status.
+ */
+public enum Status {
+
+ SUCCESS, UNEXPECTED_SUCCESS, FAIL, EXPECTED_FAIL, TIMEOUT;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/TestCase.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/*
+ * A test case for a specific TLS communication use case between two JDKs.
+ */
+public class TestCase {
+
+ public final JdkInfo serverJdk;
+ public final JdkInfo clientJdk;
+ public final UseCase useCase;
+
+ public final boolean negativeCaseOnServer;
+ public final boolean negativeCaseOnClient;
+
+ private Status status;
+
+ public TestCase(JdkInfo serverJdk, JdkInfo clientJdk, UseCase useCase) {
+ this.serverJdk = serverJdk;
+ this.clientJdk = clientJdk;
+ this.useCase = useCase;
+
+ negativeCaseOnServer = useCase.negativeCase
+ || !serverJdk.supportsCipherSuite(useCase.cipherSuite);
+ negativeCaseOnClient = useCase.negativeCase
+ || !clientJdk.supportsCipherSuite(useCase.cipherSuite);
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(Status status) {
+ this.status = status;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.join(Utils.PARAM_DELIMITER,
+ "ServerJDK=" + serverJdk.version,
+ "ClientJDK=" + clientJdk.version,
+ useCase.toString());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/UseCase.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,107 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+
+/*
+ * The TLS communication use case.
+ */
+public class UseCase {
+
+ private static final boolean FULL_CASES
+ = Utils.getBoolProperty("fullCases");
+
+ private static final Parameter[][] PARAMS = new Parameter[][] {
+ FULL_CASES ? Protocol.values() : Protocol.getMandatoryValues(),
+ FULL_CASES ? CipherSuite.values() : CipherSuite.getMandatoryValues(),
+ FULL_CASES ? ClientAuth.values() : ClientAuth.getMandatoryValues(),
+ FULL_CASES ? ServerName.values() : ServerName.getMandatoryValues(),
+ FULL_CASES ? AppProtocol.values() : AppProtocol.getMandatoryValues() };
+
+ public final Protocol protocol;
+ public final CipherSuite cipherSuite;
+ public final ClientAuth clientAuth;
+ public final ServerName serverName;
+ public final AppProtocol appProtocol;
+
+ public final boolean negativeCase;
+
+ public UseCase(
+ Protocol protocol,
+ CipherSuite cipherSuite,
+ ClientAuth clientAuth,
+ ServerName serverName,
+ AppProtocol appProtocol) {
+ this.protocol = protocol;
+ this.cipherSuite = cipherSuite;
+ this.clientAuth = clientAuth;
+ this.serverName = serverName;
+ this.appProtocol = appProtocol;
+
+ negativeCase = !cipherSuite.supportedByProtocol(protocol);
+ }
+
+ // JDK 6 doesn't support EC key algorithm.
+ public boolean ignoredByJdk(JdkInfo jdkInfo) {
+ return cipherSuite.name().contains("_EC") && !jdkInfo.supportsECKey;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.join(Utils.PARAM_DELIMITER,
+ "Protocol=" + protocol.version,
+ "CipherSuite=" + cipherSuite,
+ "ClientAuth=" + clientAuth,
+ "ServerName=" + serverName,
+ "AppProtocols=" + appProtocol);
+ }
+
+ public static List<UseCase> getAllUseCases() {
+ List<UseCase> useCases = new ArrayList<>();
+ getUseCases(PARAMS, 0, new Parameter[PARAMS.length], useCases);
+ return useCases;
+ }
+
+ private static void getUseCases(Parameter[][] params, int index,
+ Parameter[] currentValues, List<UseCase> useCases) {
+ if (index == params.length) {
+ Protocol protocol = (Protocol) currentValues[0];
+ CipherSuite cipherSuite = (CipherSuite) currentValues[1];
+
+ UseCase useCase = new UseCase(
+ protocol,
+ cipherSuite,
+ (ClientAuth) currentValues[2],
+ (ServerName) currentValues[3],
+ (AppProtocol) currentValues[4]);
+ useCases.add(useCase);
+ } else {
+ Parameter[] values = params[index];
+ for (int i = 0; i < values.length; i++) {
+ currentValues[index] = values[i];
+ getUseCases(params, index + 1, currentValues, useCases);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/Utils.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,282 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManagerFactory;
+
+/*
+ * Utilities for testing.
+ */
+public class Utils {
+
+ /* ***** Properties ***** */
+ public static final String PROP_PORT = "test.port";
+ public static final String PROP_PROTOCOL = "test.protocol";
+ public static final String PROP_CIPHER_SUITE = "test.cipher.suite";
+ public static final String PROP_CLIENT_AUTH = "test.client.auth";
+ public static final String PROP_SERVER_JDK = "test.server.jdk";
+ public static final String PROP_CLIENT_JDK = "test.client.jdk";
+ public static final String PROP_SERVER_NAME = "test.server.name";
+ public static final String PROP_APP_PROTOCOLS
+ = "test.app.protocols";
+ public static final String PROP_NEGO_APP_PROTOCOL
+ = "test.negotiated.app.protocol";
+ public static final String PROP_SUPPORTS_SNI_ON_SERVER
+ = "test.supports.sni.on.server";
+ public static final String PROP_SUPPORTS_SNI_ON_CLIENT
+ = "test.supports.sni.on.client";
+ public static final String PROP_SUPPORTS_ALPN_ON_SERVER
+ = "test.supports.alpn.on.server";
+ public static final String PROP_SUPPORTS_ALPN_ON_CLIENT
+ = "test.supports.alpn.on.client";
+ public static final String PROP_NEGATIVE_CASE_ON_SERVER
+ = "test.negative.case.on.server";
+ public static final String PROP_NEGATIVE_CASE_ON_CLIENT
+ = "test.negative.case.on.client";
+
+ public static final int TIMEOUT = 10000;
+ public static final char[] PASSWORD = "testpass".toCharArray();
+
+ public static final String TEST_LOG = "test.html";
+ public static final String PORT_LOG = "port";
+
+ public static final String HTTP_2 = "h2";
+ public static final String HTTP_1_1 = "http/1.1";
+
+ public static final String PARAM_DELIMITER = ";";
+ public static final String VALUE_DELIMITER = ",";
+
+ /*
+ * Creates SSL context with the specified certificate.
+ */
+ public static SSLContext createSSLContext(Cert... certs) throws Exception {
+ KeyStore trustStore = KeyStore.getInstance("JKS");
+ trustStore.load(null, null);
+ for (int i = 0; i < certs.length; i++) {
+ trustStore.setCertificateEntry("trust-" + certs[i].name(),
+ createCert(certs[i]));
+ }
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
+ tmf.init(trustStore);
+
+ KeyStore keyStore = KeyStore.getInstance("JKS");
+ keyStore.load(null, null);
+ for (int i = 0; i < certs.length; i++) {
+ PrivateKey privKey = createKey(certs[i]);
+ keyStore.setKeyEntry("cert-" + certs[i].name(), privKey, PASSWORD,
+ new Certificate[] { createCert(certs[i]) });
+ }
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
+ kmf.init(keyStore, PASSWORD);
+
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ return context;
+ }
+
+ private static Certificate createCert(Cert cert) throws IOException {
+ try {
+ CertificateFactory certFactory
+ = CertificateFactory.getInstance("X.509");
+ return certFactory.generateCertificate(
+ new ByteArrayInputStream(cert.certMaterials.getBytes()));
+ } catch (Exception e) {
+ throw new RuntimeException("Create key failed: " + cert, e);
+ }
+ }
+
+ private static PrivateKey createKey(Cert cert)
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
+ PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(
+ hexToBytes(cert.privKeyMaterials));
+ KeyFactory keyFactory = KeyFactory.getInstance(
+ getKeyAlgorithm(cert.signatureAlgorithm));
+ PrivateKey privKey = keyFactory.generatePrivate(privKeySpec);
+ return privKey;
+ }
+
+ private static String getKeyAlgorithm(
+ SignatureAlgorithm signatureAlgorithm) {
+ String signatureAlogrithmName = signatureAlgorithm.name();
+ return signatureAlogrithmName.equals(SignatureAlgorithm.ECDSA.name())
+ ? "EC"
+ : signatureAlogrithmName;
+ }
+
+ public static byte[] hexToBytes(String hex) {
+ if (hex == null) {
+ return null;
+ }
+
+ int length = hex.length();
+ if (length % 2 != 0) {
+ throw new IllegalArgumentException("Hex format is wrong.");
+ }
+
+ byte[] bytes = new byte[length / 2];
+ for (int i = 0; i < length; i += 2) {
+ bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ + Character.digit(hex.charAt(i + 1), 16));
+ }
+ return bytes;
+ }
+
+ public static String join(String delimiter, String... values) {
+ StringBuilder result = new StringBuilder();
+ if (values != null && values.length > 0) {
+ for (int i = 0; i < values.length - 1; i++) {
+ result.append(values[i]).append(delimiter);
+ }
+ result.append(values[values.length - 1]);
+ }
+ return result.toString();
+ }
+
+ public static String[] split(String str, String delimiter) {
+ return str == null ? new String[0] : str.split(delimiter);
+ }
+
+ public static String boolToStr(boolean bool) {
+ return bool ? "Y" : "N";
+ }
+
+ public static boolean getBoolProperty(String prop) {
+ return Boolean.valueOf(System.getProperty(prop));
+ }
+
+ public static Status handleException(Exception exception,
+ boolean negativeCase) {
+ Status status;
+ if ((exception instanceof SSLHandshakeException
+ || exception instanceof IllegalArgumentException)
+ && negativeCase) {
+ System.out.println("Expected exception: " + exception);
+ status = Status.EXPECTED_FAIL;
+ } else if (exception instanceof SocketTimeoutException) {
+ status = Status.TIMEOUT;
+ } else {
+ exception.printStackTrace(System.out);
+ status = Status.FAIL;
+ }
+ return status;
+ }
+
+ /* The HTML-related constants and methods. */
+
+ private static final String STYLE
+ = "style=\"font-family: Courier New; "
+ + "font-size: 12px; "
+ + "white-space: pre-wrap\"";
+
+ private static final String TABLE_STYLE
+ = "#test { font-family: \"Courier New\"; font-size: 12px; border-collapse: collapse; }\n"
+ + "#test td { border: 1px solid #ddd; padding: 4px; }\n"
+ + "#test tr:nth-child(odd) { background-color: #f2f2f2; }";
+
+ public static String row(Object... values) {
+ StringBuilder row = new StringBuilder();
+ row.append(startTr());
+ for (Object value : values) {
+ row.append(startTd());
+ row.append(value);
+ row.append(endTd());
+ }
+ row.append(endTr());
+ return row.toString();
+ }
+
+ public static String startHtml() {
+ return startTag("html");
+ }
+
+ public static String endHtml() {
+ return endTag("html");
+ }
+
+ public static String startPre() {
+ return startTag("pre " + STYLE);
+ }
+
+ public static String endPre() {
+ return endTag("pre");
+ }
+
+ public static String anchorName(String name, String text) {
+ return "<a name=" + name + ">" + text + "</a>";
+ }
+
+ public static String anchorLink(String file, String anchorName,
+ String text) {
+ return "<a href=" + file + "#" + anchorName + ">" + text + "</a>";
+ }
+
+ public static String tableStyle() {
+ return startTag("style") + TABLE_STYLE +endTag("style");
+ }
+
+ public static String startTable() {
+ return startTag("table id=\"test\"");
+ }
+
+ public static String endTable() {
+ return endTag("table");
+ }
+
+ private static String startTr() {
+ return startTag("tr");
+ }
+
+ private static String endTr() {
+ return endTag("tr");
+ }
+
+ private static String startTd() {
+ return startTag("td");
+ }
+
+ private static String endTd() {
+ return endTag("td");
+ }
+
+ private static String startTag(String tag) {
+ return "<" + tag + ">";
+ }
+
+ private static String endTag(String tag) {
+ return "</" + tag + ">";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/net/ssl/compatibility/java.security Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,2 @@
+jdk.certpath.disabledAlgorithms=
+jdk.tls.disabledAlgorithms=
\ No newline at end of file
--- a/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java Tue Nov 28 15:01:00 2017 -0800
+++ b/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java Wed Nov 29 09:07:01 2017 -0800
@@ -24,7 +24,7 @@
/*
* @test
* @bug 4494033 7028815 7052425 8007338 8023608 8008164 8016549 8072461 8154261 8162363 8160196 8151743 8177417
- * 8175218 8176452 8181215 8182263 8183511 8169819 8183037
+ * 8175218 8176452 8181215 8182263 8183511 8169819 8183037 8185369
* @summary Run tests on doclet stylesheet.
* @author jamieh
* @library ../lib
@@ -50,16 +50,6 @@
// TODO: most of this test seems a bit silly, since javadoc is simply
// copying in the stylesheet from the source directory
checkOutput("stylesheet.css", true,
- "/* Javadoc style sheet */",
- "/*\n"
- + "Overall document style\n"
- + "*/",
- "/*\n"
- + "Heading styles\n"
- + "*/",
- "/*\n"
- + "Navigation bar styles\n"
- + "*/",
"body {\n"
+ " background-color:#ffffff;\n"
+ " color:#353833;\n"
@@ -173,8 +163,8 @@
+ " position:relative;\n"
+ " padding-top:129px;\n"
+ " margin-top:-129px;\n"
- + "}\n"
- + ".searchTagResult:before, .searchTagResult:target {\n"
+ + "}",
+ ".searchTagResult:before, .searchTagResult:target {\n"
+ " color:red;\n"
+ "}",
"a[href]:hover, a[href]:focus {\n"
--- a/test/langtools/jdk/jshell/ForwardReferenceImportTest.java Tue Nov 28 15:01:00 2017 -0800
+++ b/test/langtools/jdk/jshell/ForwardReferenceImportTest.java Wed Nov 29 09:07:01 2017 -0800
@@ -188,7 +188,7 @@
DiagCheck.DIAG_ERROR,
added(VALID),
ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
- assertDeclareFail("A.list = Arrays.asList(1, 2, 3);", "compiler.err.already.defined.static.single.import");
+ assertDeclareFail("A.list = Arrays.asList(1, 2, 3);", "compiler.err.already.defined.single.import");
assertActiveKeys();
assertDrop(list,
ste(list, VALID, DROPPED, true, null),
--- a/test/langtools/tools/javac/4980495/std/NonStatic2StaticImportClash.java Tue Nov 28 15:01:00 2017 -0800
+++ b/test/langtools/tools/javac/4980495/std/NonStatic2StaticImportClash.java Wed Nov 29 09:07:01 2017 -0800
@@ -1,14 +1,14 @@
/*
* @test /nodynamiccopyright/
- * @bug 7101822
+ * @bug 7101822 8133616
* @summary Check the when clashing types are imported through an ordinary and static import,
* the compile-time error is properly reported.
* @compile/fail/ref=NonStatic2StaticImportClash.out -XDrawDiagnostics NonStatic2StaticImportClash.java p1/A1.java p2/A2.java
*
*/
-import p1.A1.f;
-import static p2.A2.f;
+import static p1.A1.f;
+import p2.A2.f;
public class NonStatic2StaticImportClash {
}
--- a/test/langtools/tools/javac/4980495/std/Static2NonStaticImportClash.java Tue Nov 28 15:01:00 2017 -0800
+++ b/test/langtools/tools/javac/4980495/std/Static2NonStaticImportClash.java Wed Nov 29 09:07:01 2017 -0800
@@ -1,14 +1,14 @@
/*
* @test /nodynamiccopyright/
- * @bug 7101822
+ * @bug 7101822 8133616
* @summary Check the when clashing types are imported through an ordinary and static import,
* the compile-time error is properly reported.
* @compile/fail/ref=Static2NonStaticImportClash.out -XDrawDiagnostics Static2NonStaticImportClash.java p1/A1.java p2/A2.java
*
*/
-import static p2.A2.f;
-import p1.A1.f;
+import p2.A2.f;
+import static p1.A1.f;
public class Static2NonStaticImportClash {
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/analyzer/LambdaWithMethod.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,17 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8191981
+ * @compile/fail/ref=LambdaWithMethod.out -Werror -XDrawDiagnostics -XDfind=lambda LambdaWithMethod.java
+ */
+
+public class LambdaWithMethod {
+ public static void run(Runnable r) {
+ run(new Runnable() {
+ public void run() {
+ put(get());
+ }
+ });
+ }
+ private static String get() { return null; }
+ private static void put(String i) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/analyzer/LambdaWithMethod.out Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,4 @@
+LambdaWithMethod.java:9:28: compiler.warn.potential.lambda.found
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- a/test/langtools/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java Tue Nov 28 15:01:00 2017 -0800
+++ b/test/langtools/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java Wed Nov 29 09:07:01 2017 -0800
@@ -23,5 +23,5 @@
// key: compiler.err.already.defined.static.single.import
-import p.E1.A;
-import static p.E2.A;
+import static p.E1.A;
+import p.E2.A;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/generics/inference/8178427/T8178427.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,57 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8178427
+ * @summary NPE in Infer$CheckUpperBounds
+ * @compile T8178427.java
+ */
+
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.function.*;
+import java.util.stream.*;
+
+abstract class X {
+ public interface N<K, V> {
+ Stream<V> getValues();
+ }
+
+ abstract <K, V> N<K, V> c();
+
+ abstract <T, K, V, M extends N<K, V>> Collector<T, ?, M> f(
+ Function<? super T, ? extends K> k,
+ Function<? super T, ? extends Stream<? extends V>> v,
+ Supplier<M> multimapSupplier);
+
+ void m(Map<String, N<?, ?>> c, ExecutorService s) {
+ s.submit(() -> {
+ return c.entrySet().parallelStream()
+ .collect(f(Map.Entry::getKey, e -> e.getValue().getValues(), this::c));
+ });
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/processing/model/util/TestTypeKindVisitors.java Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2013, 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 8191234
+ * @summary Test TypeKind visitors on pseudo types.
+ * @library /tools/javac/lib
+ * @modules java.compiler
+ * @build JavacTestingAbstractProcessor TestTypeKindVisitors
+ * @compile -processor TestTypeKindVisitors -proc:only TestTypeKindVisitors.java
+ */
+
+import java.lang.annotation.Annotation;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+import static javax.lang.model.SourceVersion.*;
+
+public class TestTypeKindVisitors extends JavacTestingAbstractProcessor {
+ @Override
+ public boolean process(Set<? extends TypeElement> tes,
+ RoundEnvironment round) {
+ if (round.processingOver())
+ return true;
+
+ List<NoType> tradNoTypes = List.of(types.getNoType(TypeKind.NONE),
+ types.getNoType(TypeKind.VOID),
+ getPackageNoType());
+ NoType moduleNoType = getModuleNoType();
+
+ // For KindVisitors based on 6, 7, and 8
+ for (TypeVisitor<TypeKind, String> visitor : getVisitors()) {
+ System.out.println(visitor.getClass().getSuperclass().getName());
+
+ for (NoType noType : tradNoTypes) {
+ System.out.println("\t" + noType.toString());
+ checkTypeKind(noType.getKind(), visitor.visit(noType));
+ }
+
+ if (RELEASE_9.compareTo(visitor.getClass().getSuperclass().
+ getAnnotation(SupportedSourceVersion.class).
+ value()) > 0) {
+ try {
+ System.out.println("\t" + moduleNoType.toString());
+ visitor.visit(moduleNoType);
+ } catch (UnknownTypeException ute) {
+ ; // Expected
+ }
+ } else {
+ checkTypeKind(moduleNoType.getKind(), visitor.visit(moduleNoType));
+ }
+ }
+
+ return true;
+ }
+
+ private NoType getPackageNoType() {
+ TypeMirror type = elements.getPackageElement("java.lang").asType();
+ checkTypeKind(TypeKind.PACKAGE, type.getKind());
+ return (NoType) type;
+ }
+
+ private NoType getModuleNoType() {
+ TypeMirror type = elements.getModuleElement("java.base").asType();
+ checkTypeKind(TypeKind.MODULE, type.getKind());
+ return (NoType) type;
+ }
+
+ private void checkTypeKind(TypeKind expected, TypeKind retreived) {
+ if (retreived != expected)
+ throw new AssertionError("Unexpected type kind " + retreived);
+ }
+
+ List<TypeVisitor<TypeKind, String>> getVisitors() {
+ return List.of(new TypeKindVisitor6<>(null) {
+ @Override
+ protected TypeKind defaultAction(TypeMirror e, String p) {
+ throw new AssertionError("Should not reach");
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsVoid(NoType t, String p) {
+ return t.getKind();
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsNone(NoType t, String p) {
+ return t.getKind();
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsPackage(NoType t, String p) {
+ return t.getKind();
+ }
+ // Leave default behavior for a NoType module
+ },
+
+ new TypeKindVisitor7<>(null){
+ @Override
+ protected TypeKind defaultAction(TypeMirror e, String p) {
+ throw new AssertionError("Should not reach");
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsVoid(NoType t, String p) {
+ return t.getKind();
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsNone(NoType t, String p) {
+ return t.getKind();
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsPackage(NoType t, String p) {
+ return t.getKind();
+ }
+ // Leave default behavior for a NoType module
+
+ },
+
+ new TypeKindVisitor8<>(null){
+ @Override
+ protected TypeKind defaultAction(TypeMirror e, String p) {
+ throw new AssertionError("Should not reach");
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsVoid(NoType t, String p) {
+ return t.getKind();
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsNone(NoType t, String p) {
+ return t.getKind();
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsPackage(NoType t, String p) {
+ return t.getKind();
+ }
+ // Leave default behavior for a NoType module
+
+ },
+
+ new TypeKindVisitor9<>(null){
+ @Override
+ protected TypeKind defaultAction(TypeMirror e, String p) {
+ throw new AssertionError("Should not reach");
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsVoid(NoType t, String p) {
+ return t.getKind();
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsNone(NoType t, String p) {
+ return t.getKind();
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsPackage(NoType t, String p) {
+ return t.getKind();
+ }
+
+ @Override
+ public TypeKind visitNoTypeAsModule(NoType t, String p) {
+ return t.getKind();
+ }
+ });
+ }
+}
--- a/test/langtools/tools/jdeps/MultiReleaseJar.java Tue Nov 28 15:01:00 2017 -0800
+++ b/test/langtools/tools/jdeps/MultiReleaseJar.java Wed Nov 29 09:07:01 2017 -0800
@@ -240,17 +240,26 @@
cmds[0] = cmdPath.resolve(cmds[0]).toString();
ProcessBuilder pb = new ProcessBuilder(cmds);
pb.directory(mrjar.toFile());
- Process p = pb.start();
- p.waitFor(10, TimeUnit.SECONDS);
- String out;
- try (InputStream is = p.getInputStream()) {
- out = new String(is.readAllBytes());
+ Process p = null;
+ try {
+ p = pb.start();
+ p.waitFor();
+
+ String out;
+ try (InputStream is = p.getInputStream()) {
+ out = new String(is.readAllBytes());
+ }
+ String err;
+ try (InputStream is = p.getErrorStream()) {
+ err = new String(is.readAllBytes());
+ }
+ return new Result(cmd, p.exitValue(), out, err);
+ } catch (Throwable t) {
+ if (p != null) {
+ p.destroyForcibly().waitFor();
+ }
+ throw t;
}
- String err;
- try (InputStream is = p.getErrorStream()) {
- err = new String(is.readAllBytes());
- }
- return new Result(cmd, p.exitValue(), out, err);
}
void checkResult(Result r) throws Exception {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/basic/es6/JDK-8059835.js Wed Nov 29 09:07:01 2017 -0800
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8059835: Optimistic splitting doesn't work with let and const
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ * @option -Dnashorn.compiler.splitter.threshold=100
+ * @fork
+ */
+
+function f() {
+ let sum = 0;
+ const c = 13;
+ if (true) {
+ let x = 0;
+ const y = 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ sum += x;
+ sum += y;
+ }
+ outer: while (true) {
+ let x = 0;
+ const y = 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ sum += x;
+ sum += y;
+ sum += c;
+ let i = 0;
+ const k = 1;
+ while (true) {
+ x += k;
+ if (++i === 10) {
+ break outer;
+ }
+ }
+ x += k;
+ }
+ return sum;
+}
+
+function g() {
+ let sum = 0;
+ const c = 13;
+ if (true) {
+ let x = 0;
+ const y = 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ sum += x;
+ sum += y;
+ }
+ outer: while (true) {
+ let x = 0;
+ const y = 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ x += 1;
+ sum += x;
+ sum += y;
+ sum += c;
+ let i = 0;
+ const k = 1;
+ while (true) {
+ x += k;
+ if (++i === 10) return 'abc';
+ }
+ x += k;
+ }
+ return sum;
+}
+
+Assert.assertTrue(f() === 80);
+Assert.assertTrue(g() === 'abc');