From a3c0889315e194a7100ec989c5ecc1d9621a03b6 Mon Sep 17 00:00:00 2001
From: Serguei Spitsyn
Date: Wed, 25 Feb 2015 01:02:04 -0800
Subject: [PATCH 1/6] 8046246: the
constantPoolCacheOopDesc::adjust_method_entries() used in RedefineClasses
does not scale
Add new test java/lang/instrument/ManyMethodsBenchmarkAgent.java
Reviewed-by: coleenp, dcubed
---
.../instrument/ManyMethodsBenchmarkAgent.java | 75 ++++++++++
.../instrument/ManyMethodsBenchmarkApp.java | 141 ++++++++++++++++++
2 files changed, 216 insertions(+)
create mode 100644 jdk/test/java/lang/instrument/ManyMethodsBenchmarkAgent.java
create mode 100644 jdk/test/java/lang/instrument/ManyMethodsBenchmarkApp.java
diff --git a/jdk/test/java/lang/instrument/ManyMethodsBenchmarkAgent.java b/jdk/test/java/lang/instrument/ManyMethodsBenchmarkAgent.java
new file mode 100644
index 00000000000..05f9f1942ff
--- /dev/null
+++ b/jdk/test/java/lang/instrument/ManyMethodsBenchmarkAgent.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015, 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 8046246
+ * @summary Tests and benchmarks the JVMTI RedefineClasses when a
+ * single class (and its parent) contains many methods.
+ *
+ * @run build ManyMethodsBenchmarkApp ManyMethodsBenchmarkAgent
+ * @run shell MakeJAR3.sh ManyMethodsBenchmarkAgent 'Can-Retransform-Classes: true'
+ * @run main/othervm -javaagent:ManyMethodsBenchmarkAgent.jar ManyMethodsBenchmarkApp
+ */
+import java.lang.instrument.*;
+
+public class ManyMethodsBenchmarkAgent
+{
+ public static boolean fail = false;
+ public static boolean completed = false;
+ private static Instrumentation instrumentation;
+
+ public static void
+ premain( String agentArgs,
+ Instrumentation instrumentation) {
+ System.out.println("ManyMethodsBenchmarkAgent started");
+ ManyMethodsBenchmarkAgent.instrumentation = instrumentation;
+ System.out.println("ManyMethodsBenchmarkAgent finished");
+ }
+
+ static void instr() {
+ System.out.println("ManyMethodsBenchmarkAgent.instr started");
+
+ Class[] allClasses = instrumentation.getAllLoadedClasses();
+
+ for (int i = 0; i < allClasses.length; i++) {
+ Class klass = allClasses[i];
+ String name = klass.getName();
+ if (!name.equals("Base")) {
+ continue;
+ }
+ System.err.println("Instrumenting the class: " + klass);
+
+ try {
+ instrumentation.retransformClasses(klass);
+ } catch (Throwable e) {
+ System.err.println("Error: bad return from retransform: " + klass);
+ System.err.println(" ERROR: " + e);
+ fail = true;
+ }
+ }
+ completed = true;
+ System.out.println("ManyMethodsBenchmarkAgent.instr finished");
+ }
+
+}
diff --git a/jdk/test/java/lang/instrument/ManyMethodsBenchmarkApp.java b/jdk/test/java/lang/instrument/ManyMethodsBenchmarkApp.java
new file mode 100644
index 00000000000..c85bf42b820
--- /dev/null
+++ b/jdk/test/java/lang/instrument/ManyMethodsBenchmarkApp.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2015 Google Inc. 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.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.List;
+import javax.tools.JavaCompiler;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * A manual benchmark of the JVMTI RedefineClasses when a
+ * single class (and its parent) contains many methods.
+ */
+public class ManyMethodsBenchmarkApp {
+ // Limit is 64k but we can not put such many as the CP limit is 32k.
+ // In practice, it means a real limit is much lower (less than 22000).
+ static final int METHOD_COUNT = 20000;
+
+ static Class> loadClassInNewClassLoader(String className) throws Exception {
+ URL[] urls = { new File(".").toURI().toURL() };
+ URLClassLoader ucl = new URLClassLoader(urls, null);
+ Class> klazz = Class.forName(className, true, ucl);
+ return klazz;
+ }
+
+ static void benchmarkClassOperations(String className) throws Exception {
+ Class> klazz = loadClassInNewClassLoader(className);
+
+ Method[] methods = klazz.getDeclaredMethods();
+ if (methods.length != METHOD_COUNT) {
+ throw new AssertionError("unexpected method count: " + methods.length +
+ " expected: " + METHOD_COUNT);
+ }
+
+ methods = klazz.getMethods();
+ // returned methods includes those inherited from Object
+ int objectMethodSlop = 100;
+ if (methods.length <= METHOD_COUNT ||
+ methods.length >= METHOD_COUNT + objectMethodSlop) {
+ throw new AssertionError("unexpected method count: " + methods.length);
+ }
+
+ // Invoke methods to make them appear in the constant pool cache
+ Object obj = klazz.newInstance();
+ Object[] args = new Object[0];
+ for (Method m: methods) {
+ try {
+ Class>[] types = m.getParameterTypes();
+ String name = m.getName();
+ // System.out.println("method: " + name + "; argno: " + types.length);
+ if (types.length == 0 && name.length() == 2 && name.startsWith("f")) {
+ m.invoke(obj, args);
+ }
+ } catch (InvocationTargetException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("test started: ManyMethodsBenchmarkApp");
+
+ // Create source files with many methods
+ File base = new File("Base.java");
+ try (FileWriter fw = new FileWriter(base)) {
+ fw.write("public class Base {\n");
+ final int L = 10;
+ // Each of the first L methods makes calls to its own chunk of METHOD_COUNT/L methods
+ for (int k = 0; k < L; k++) {
+ fw.write(" public void f" + k + "() {\n");
+ int shift = (k == 0) ? L : 0;
+ for (int i = (k * (METHOD_COUNT/L)) + shift; i < (k + 1) * METHOD_COUNT/L; i++) {
+ fw.write(" f" + i + "();\n");
+ }
+ fw.write(" }\n");
+ }
+
+ // The rest of (METHOD_COUNT - L) methods have empty body
+ for (int i = L; i < METHOD_COUNT; i++) {
+ fw.write(" public static void f" + i + "() {}\n");
+ }
+ fw.write("}\n");
+ }
+
+ // Compile the generated source files.
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ List files = Arrays.asList(new File[] { base });
+ try (StandardJavaFileManager fileManager =
+ compiler.getStandardFileManager(null, null, null)) {
+ compiler.getTask(null, fileManager, null, null, null,
+ fileManager.getJavaFileObjectsFromFiles(files))
+ .call();
+ }
+
+ benchmarkClassOperations("Base");
+
+ ManyMethodsBenchmarkAgent.instr();
+
+ // Cleanup
+ base.delete();
+ new File("Base.class").delete();
+ if (!ManyMethodsBenchmarkAgent.completed) {
+ throw new Exception("ERROR: ManyMethodsBenchmarkAgent did not complete.");
+ }
+
+ if (ManyMethodsBenchmarkAgent.fail) {
+ throw new Exception("ERROR: ManyMethodsBenchmarkAgent failed.");
+ } else {
+ System.out.println("ManyMethodsBenchmarkAgent succeeded.");
+ }
+ System.out.println("test finished: ManyMethodsBenchmarkApp");
+ }
+}
From 02614afbd146d397421307c4d8de0673f3be4d7a Mon Sep 17 00:00:00 2001
From: Zaiyao Liu
Date: Fri, 6 Mar 2015 00:49:38 +0000
Subject: [PATCH 2/6] 8044193: Need to add known answer tests for AES cipher
Added more tests for AES cipher using known test vectors.
Reviewed-by: valeriep
---
.../Cipher/AES/TestAESCiphers/Dynamic.java | 186 ++++++++++++++++++
.../TestAESWithDefaultProvider.java | 35 ++++
.../TestAESWithProviderChange.java | 39 ++++
.../TestAESWithRemoveAddProvider.java | 42 ++++
.../Cipher/AES/TestAESCiphers/testAES.policy | 6 +
5 files changed, 308 insertions(+)
create mode 100644 jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/Dynamic.java
create mode 100644 jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java
create mode 100644 jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java
create mode 100644 jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java
create mode 100644 jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/testAES.policy
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/Dynamic.java b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/Dynamic.java
new file mode 100644
index 00000000000..3aa6d29e8fe
--- /dev/null
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/Dynamic.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2012, 2015, 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.PrintStream;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.Random;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+public class Dynamic {
+
+ static final String ALGORITHM = "AES";
+ static final String[] MODE = {
+ "ECb", "CbC", "CTR", "PCBC", "OFB", "OFB150", "cFB", "CFB7",
+ "cFB8", "cFB16", "cFB24", "cFB32", "Cfb40", "cfB48", "cfB56",
+ "cfB64", "cfB72", "cfB80", "cfB88", "cfB96", "cfb104", "cfB112",
+ "cfB120", "cfB128", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40",
+ "OFB48", "OFB56", "OFB64", "OFB72", "OFB80", "OFB88", "OFB96",
+ "OFB104", "OFB112", "OFB120", "OFB128", "GCM"
+ };
+ static final String[] PADDING = {
+ "NoPadding", "PKCS5Padding", "ISO10126Padding"
+ };
+ static final String SUNJCE = "SunJCE";
+
+ Cipher ci = null;
+ byte[] iv = null;
+ AlgorithmParameterSpec aps = null;
+ SecretKey key = null;
+ int keyStrength;
+ static int DefaultSize = 128;
+
+ public void run(String[] argv) throws Exception {
+ if (!runAllTest(argv, System.out)) {
+ throw new Exception("Test Failed");
+ }
+ }
+
+ protected boolean runAllTest(String argv[], PrintStream out) {
+ boolean result = true;
+ StringBuilder failedList = new StringBuilder();
+ int failedCnt = 0;
+ int testCount = 0;
+ int padKinds; // how many kinds of padding mode such as PKCS5padding and
+ // NoPadding.
+
+ try {
+ for (int i = 0; i < 3; i++) {
+ keyStrength = DefaultSize + i * 64; // obtain the key size 128,
+ // 192, 256
+
+ for (int j = 0; j < MODE.length; j++) {
+ if (MODE[j].equalsIgnoreCase("ECB")
+ || MODE[j].equalsIgnoreCase("PCBC")
+ || MODE[j].equalsIgnoreCase("CBC")) {
+ padKinds = PADDING.length;
+ } else {
+ padKinds = 1;
+ }
+
+ for (int k = 0; k < padKinds; k++) {
+ testCount++;
+ try {
+ if (!runTest(ALGORITHM, MODE[j], PADDING[k])) {
+ result = false;
+ failedCnt++;
+ failedList.append(ALGORITHM + "/" + MODE[j]
+ + "/" + PADDING[k] + " ");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ result = false;
+ failedCnt++;
+ failedList.append(ALGORITHM + "/" + MODE[j] + "/"
+ + PADDING[k] + " ");
+ }
+
+ }
+ }
+ }
+
+ if (result) {
+ out.println("STATUS:Passed. Test " + testCount
+ + " cases, All Passed");
+ return true;
+ }
+ out.println("STATUS:Failed. " + failedCnt + " Failed: "
+ + failedList);
+ return false;
+
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ out.println("STATUS:Failed. Unexpected Exception: " + ex);
+ return false;
+ }
+ }
+
+ protected boolean runTest(String algo, String mo, String pad)
+ throws Exception {
+ boolean result = true;
+ try {
+ byte[] plainText = new byte[160000];
+ new Random().nextBytes(plainText);
+
+ String transformation = algo + "/" + mo + "/" + pad;
+ ci = Cipher.getInstance(transformation, SUNJCE);
+ KeyGenerator kg = KeyGenerator.getInstance(algo, SUNJCE);
+ if (keyStrength > Cipher.getMaxAllowedKeyLength(transformation)) {
+ // skip if this key length is larger than what's
+ // configured in the jce jurisdiction policy files
+ System.out.println(keyStrength
+ + " is larger than what's configured "
+ + "in the jce jurisdiction policy files");
+ return result;
+ }
+ kg.init(keyStrength);
+ key = kg.generateKey();
+
+ if (!mo.equalsIgnoreCase("GCM")) {
+ ci.init(Cipher.ENCRYPT_MODE, key, aps);
+ } else {
+ ci.init(Cipher.ENCRYPT_MODE, key);
+ }
+ byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
+ int offset = ci.update(plainText, 0, plainText.length, cipherText,
+ 0);
+ ci.doFinal(cipherText, offset);
+
+ if (!mo.equalsIgnoreCase("ECB")) {
+ iv = ci.getIV();
+ aps = new IvParameterSpec(iv);
+ } else {
+ aps = null;
+ }
+
+ if (!mo.equalsIgnoreCase("GCM")) {
+ ci.init(Cipher.DECRYPT_MODE, key, aps);
+ } else {
+ ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters());
+ }
+ byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
+ int len = ci.doFinal(cipherText, 0, cipherText.length,
+ recoveredText);
+
+ byte[] tmp = new byte[len];
+ for (int i = 0; i < len; i++) {
+ tmp[i] = recoveredText[i];
+ }
+
+ result = Arrays.equals(plainText, tmp);
+ } catch (NoSuchAlgorithmException nsaEx) {
+ nsaEx.printStackTrace();
+ // CFB7 and OFB150 are negative test,SunJCE not support this
+ // algorithm
+ result = mo.equalsIgnoreCase("CFB7")
+ || mo.equalsIgnoreCase("OFB150");
+
+ }
+ return result;
+ }
+}
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java
new file mode 100644
index 00000000000..132e79d9a35
--- /dev/null
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2015, 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 8044193
+ * @summary Test AES ciphers with different modes and padding schemes with
+ * default provider
+ */
+
+public class TestAESWithDefaultProvider extends Dynamic {
+ public static void main(String argv[]) throws Exception {
+ new TestAESWithDefaultProvider().run(argv);
+ }
+}
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java
new file mode 100644
index 00000000000..8dec9f136a4
--- /dev/null
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java
@@ -0,0 +1,39 @@
+/* Copyright (c) 2012, 2015, 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.Security;
+
+/*
+ * @test
+ * @bug 8044193
+ * @summary Test AES ciphers with different modes and padding schemes after
+ * remove then add provider.
+ * @run main/othervm/policy=testAES.policy TestAESWithProviderChange
+ */
+
+public class TestAESWithProviderChange extends Dynamic {
+ public static void main(String argv[]) throws Exception {
+ Security.removeProvider(SUNJCE);
+ Security.addProvider(new com.sun.crypto.provider.SunJCE());
+ new TestAESWithProviderChange().run(argv);
+ }
+}
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java
new file mode 100644
index 00000000000..81761a7ea4b
--- /dev/null
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2015, 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.*;
+import java.security.Provider;
+
+/*
+ * @test
+ * @bug 8044193
+ * @summary Test AES ciphers with different modes and padding schemes after
+ * remove default provider then add it back.
+ * @run main/othervm/policy=testAES.policy TestAESWithRemoveAddProvider
+ */
+
+public class TestAESWithRemoveAddProvider extends Dynamic {
+ public static void main(String argv[]) throws Exception {
+ Provider pJCE = Security.getProvider(SUNJCE);
+ Security.removeProvider(SUNJCE);
+ Security.addProvider(pJCE);
+ new TestAESWithRemoveAddProvider().run(argv);
+ }
+}
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/testAES.policy b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/testAES.policy
new file mode 100644
index 00000000000..a138a577ff7
--- /dev/null
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/testAES.policy
@@ -0,0 +1,6 @@
+grant
+{
+ permission java.security.SecurityPermission "removeProvider.SunJCE";
+ permission java.security.SecurityPermission "insertProvider.SunJCE";
+ permission java.security.SecurityPermission "putProviderProperty.SunJCE";
+};
From b035ca734821fa7874c9f6167183bb3e48f50109 Mon Sep 17 00:00:00 2001
From: Ivan Gerasimov
Date: Fri, 6 Mar 2015 13:30:49 +0300
Subject: [PATCH 3/6] 8073692: (cs) Inconsistent docs for
CharsetDecoder.replaceWith and CharsetEncoder.replaceWith
Reviewed-by: martin
---
.../java/nio/charset/Charset-X-Coder.java.template | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/jdk/src/java.base/share/classes/java/nio/charset/Charset-X-Coder.java.template b/jdk/src/java.base/share/classes/java/nio/charset/Charset-X-Coder.java.template
index f5e50a51c85..faa51bb45d4 100644
--- a/jdk/src/java.base/share/classes/java/nio/charset/Charset-X-Coder.java.template
+++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset-X-Coder.java.template
@@ -266,16 +266,15 @@ public abstract class Charset$Coder$ {
* method, passing the new replacement, after checking that the new
* replacement is acceptable.
*
- * @param newReplacement The replacement value
- *
+ * @param newReplacement The new replacement; must not be
+ * null, must have non-zero length,
#if[decoder]
- * The new replacement; must not be null
- * and must have non-zero length
+ * and must not be longer than the value returned by the
+ * {@link #max$ItypesPerOtype$() max$ItypesPerOtype$} method
#end[decoder]
#if[encoder]
- * The new replacement; must not be null, must have
- * non-zero length, must not be longer than the value returned by
- * the {@link #max$ItypesPerOtype$() max$ItypesPerOtype$} method, and
+ * must not be longer than the value returned by the
+ * {@link #max$ItypesPerOtype$() max$ItypesPerOtype$} method, and
* must be {@link #isLegalReplacement legal}
#end[encoder]
*
From 1c5857f8dddb09330f28f42762e407b43296e100 Mon Sep 17 00:00:00 2001
From: Jaroslav Bachorik
Date: Tue, 10 Mar 2015 09:37:56 +0100
Subject: [PATCH 4/6] 6712222: Race condition in
java/lang/management/ThreadMXBean/AllThreadIds.java
Reviewed-by: dholmes, dfuchs
---
.../management/ThreadMXBean/AllThreadIds.java | 99 +++++++++----------
1 file changed, 49 insertions(+), 50 deletions(-)
diff --git a/jdk/test/java/lang/management/ThreadMXBean/AllThreadIds.java b/jdk/test/java/lang/management/ThreadMXBean/AllThreadIds.java
index 05547b78001..aa80c746cf2 100644
--- a/jdk/test/java/lang/management/ThreadMXBean/AllThreadIds.java
+++ b/jdk/test/java/lang/management/ThreadMXBean/AllThreadIds.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -27,21 +27,19 @@
* @summary Basic unit test of ThreadMXBean.getAllThreadIds()
* @author Alexei Guibadoulline and Mandy Chung
*
- * @run build Barrier
* @run main/othervm AllThreadIds
*/
import java.lang.management.*;
-import java.util.*;
+import java.util.concurrent.Phaser;
public class AllThreadIds {
final static int DAEMON_THREADS = 20;
final static int USER_THREADS = 5;
final static int ALL_THREADS = DAEMON_THREADS + USER_THREADS;
- private static volatile boolean live[] = new boolean[ALL_THREADS];
- private static Thread allThreads[] = new Thread[ALL_THREADS];
- private static ThreadMXBean mbean
- = ManagementFactory.getThreadMXBean();
+ private static final boolean live[] = new boolean[ALL_THREADS];
+ private static final Thread allThreads[] = new Thread[ALL_THREADS];
+ private static final ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
private static boolean testFailed = false;
private static boolean trace = false;
@@ -52,8 +50,7 @@ public class AllThreadIds {
private static int curLiveThreadCount = 0;
private static int curPeakThreadCount = 0;
- // barrier for threads communication
- private static Barrier barrier = new Barrier(ALL_THREADS);
+ private static final Phaser startupCheck = new Phaser(ALL_THREADS + 1);
private static void printThreadList() {
if (!trace) return;
@@ -124,18 +121,15 @@ public class AllThreadIds {
curPeakThreadCount = mbean.getPeakThreadCount();
checkThreadCount(0, 0);
-
// Start all threads and wait to be sure they all are alive
- barrier.set(ALL_THREADS);
for (int i = 0; i < ALL_THREADS; i++) {
- live[i] = true;
+ setLive(i, true);
allThreads[i] = new MyThread(i);
- allThreads[i].setDaemon( (i < DAEMON_THREADS) ? true : false);
+ allThreads[i].setDaemon(i < DAEMON_THREADS);
allThreads[i].start();
}
// wait until all threads are started.
- barrier.await();
-
+ startupCheck.arriveAndAwaitAdvance();
checkThreadCount(ALL_THREADS, 0);
printThreadList();
@@ -173,15 +167,14 @@ public class AllThreadIds {
// Stop daemon threads, wait to be sure they all are dead, and check
// that they disappeared from getAllThreadIds() list
- barrier.set(DAEMON_THREADS);
for (int i = 0; i < DAEMON_THREADS; i++) {
- live[i] = false;
+ setLive(i, false);
}
- // wait until daemon threads are terminated.
- barrier.await();
- // give chance to threads to terminate
- pause();
+ // make sure the daemon threads are completely dead
+ joinDaemonThreads();
+
+ // and check the reported thread count
checkThreadCount(0, DAEMON_THREADS);
// Check mbean now
@@ -190,11 +183,11 @@ public class AllThreadIds {
for (int i = 0; i < ALL_THREADS; i++) {
long expectedId = allThreads[i].getId();
boolean found = false;
- boolean live = (i >= DAEMON_THREADS);
+ boolean alive = (i >= DAEMON_THREADS);
if (trace) {
System.out.print("Looking for thread with id " + expectedId +
- (live ? " expected alive." : " expected terminated."));
+ (alive ? " expected alive." : " expected terminated."));
}
for (int j = 0; j < list.length; j++) {
if (expectedId == list[j]) {
@@ -203,11 +196,11 @@ public class AllThreadIds {
}
}
- if (live != found) {
+ if (alive != found) {
testFailed = true;
}
if (trace) {
- if (live != found) {
+ if (alive != found) {
System.out.println(" TEST FAILED.");
} else {
System.out.println();
@@ -216,15 +209,14 @@ public class AllThreadIds {
}
// Stop all threads and wait to be sure they all are dead
- barrier.set(ALL_THREADS - DAEMON_THREADS);
for (int i = DAEMON_THREADS; i < ALL_THREADS; i++) {
- live[i] = false;
+ setLive(i, false);
}
- // wait until daemon threads are terminated .
- barrier.await();
- // give chance to threads to terminate
- pause();
+ // make sure the non-daemon threads are completely dead
+ joinNonDaemonThreads();
+
+ // and check the thread count
checkThreadCount(0, ALL_THREADS - DAEMON_THREADS);
if (testFailed)
@@ -233,6 +225,30 @@ public class AllThreadIds {
System.out.println("Test passed.");
}
+ private static void joinDaemonThreads() throws InterruptedException {
+ for (int i = 0; i < DAEMON_THREADS; i++) {
+ allThreads[i].join();
+ }
+ }
+
+ private static void joinNonDaemonThreads() throws InterruptedException {
+ for (int i = DAEMON_THREADS; i < ALL_THREADS; i++) {
+ allThreads[i].join();
+ }
+ }
+
+ private static void setLive(int i, boolean val) {
+ synchronized(live) {
+ live[i] = val;
+ }
+ }
+
+ private static boolean isLive(int i) {
+ synchronized(live) {
+ return live[i];
+ }
+ }
+
// The MyThread thread lives as long as correspondent live[i] value is true
private static class MyThread extends Thread {
int id;
@@ -243,8 +259,8 @@ public class AllThreadIds {
public void run() {
// signal started
- barrier.signal();
- while (live[id]) {
+ startupCheck.arrive();
+ while (isLive(id)) {
try {
sleep(100);
} catch (InterruptedException e) {
@@ -253,23 +269,6 @@ public class AllThreadIds {
testFailed = true;
}
}
- // signal about to exit
- barrier.signal();
}
}
-
- private static Object pauseObj = new Object();
- private static void pause() {
- // Enter lock a without blocking
- synchronized (pauseObj) {
- try {
- // may need to tune this timeout for different platforms
- pauseObj.wait(50);
- } catch (Exception e) {
- System.err.println("Unexpected exception.");
- e.printStackTrace(System.err);
- }
- }
- }
-
}
From 996a61cf68a28190d1ec90bd1fa50b7d8199bfa4 Mon Sep 17 00:00:00 2001
From: Jaroslav Bachorik
Date: Tue, 10 Mar 2015 20:25:48 +0100
Subject: [PATCH 5/6] 8049696: com/sun/jdi/RunToExit fails with
"ConnectException: Connection refused"
Reviewed-by: sla
---
jdk/test/com/sun/jdi/RunToExit.java | 117 +++++++-----------
.../jdk/testlibrary/ProcessTools.java | 62 +++++++---
2 files changed, 91 insertions(+), 88 deletions(-)
diff --git a/jdk/test/com/sun/jdi/RunToExit.java b/jdk/test/com/sun/jdi/RunToExit.java
index 01a15c85697..f76f4b0b9fa 100644
--- a/jdk/test/com/sun/jdi/RunToExit.java
+++ b/jdk/test/com/sun/jdi/RunToExit.java
@@ -24,74 +24,29 @@
/* @test
* @bug 4997445
* @summary Test that with server=y, when VM runs to System.exit() no error happens
- *
- * @build VMConnection RunToExit Exit0
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.* VMConnection RunToExit Exit0
* @run driver RunToExit
*/
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.File;
-import java.io.BufferedInputStream;
import java.net.ServerSocket;
import com.sun.jdi.Bootstrap;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.*;
import com.sun.jdi.connect.Connector;
import com.sun.jdi.connect.AttachingConnector;
+import java.net.ConnectException;
import java.util.Map;
import java.util.List;
import java.util.Iterator;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import jdk.testlibrary.ProcessTools;
public class RunToExit {
/* Increment this when ERROR: seen */
- static int error_seen = 0;
+ static volatile int error_seen = 0;
static volatile boolean ready = false;
- /*
- * Helper class to direct process output to a StringBuffer
- */
- static class IOHandler implements Runnable {
- private String name;
- private BufferedInputStream in;
- private StringBuffer buffer;
-
- IOHandler(String name, InputStream in) {
- this.name = name;
- this.in = new BufferedInputStream(in);
- this.buffer = new StringBuffer();
- }
-
- static void handle(String name, InputStream in) {
- IOHandler handler = new IOHandler(name, in);
- Thread thr = new Thread(handler);
- thr.setDaemon(true);
- thr.start();
- }
-
- public void run() {
- try {
- byte b[] = new byte[100];
- for (;;) {
- int n = in.read(b, 0, 100);
- // The first thing that will get read is
- // Listening for transport dt_socket at address: xxxxx
- // which shows the debuggee is ready to accept connections.
- ready = true;
- if (n < 0) {
- break;
- }
- buffer.append(new String(b, 0, n));
- }
- } catch (IOException ioe) { }
-
- String str = buffer.toString();
- if ( str.contains("ERROR:") ) {
- error_seen++;
- }
- System.out.println(name + ": " + str);
- }
-
- }
/*
* Find a connector by name
@@ -111,24 +66,40 @@ public class RunToExit {
/*
* Launch a server debuggee with the given address
*/
- private static Process launch(String address, String class_name) throws IOException {
- String exe = System.getProperty("java.home")
- + File.separator + "bin" + File.separator + "java";
- String cmd = exe + " " + VMConnection.getDebuggeeVMOptions() +
- " -agentlib:jdwp=transport=dt_socket" +
- ",server=y" + ",suspend=y" + ",address=" + address +
- " " + class_name;
+ private static Process launch(String address, String class_name) throws Exception {
+ String args[] = new String[]{
+ "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address="
+ + address,
+ class_name
+ };
+ args = VMConnection.insertDebuggeeVMOptions(args);
- System.out.println("Starting: " + cmd);
+ ProcessBuilder launcher = ProcessTools.createJavaProcessBuilder(args);
- Process p = Runtime.getRuntime().exec(cmd);
+ System.out.println(launcher.command().stream().collect(Collectors.joining(" ", "Starting: ", "")));
- IOHandler.handle("Input Stream", p.getInputStream());
- IOHandler.handle("Error Stream", p.getErrorStream());
+ Process p = ProcessTools.startProcess(
+ class_name,
+ launcher,
+ RunToExit::checkForError,
+ RunToExit::isTransportListening,
+ 0,
+ TimeUnit.NANOSECONDS
+ );
return p;
}
+ private static boolean isTransportListening(String line) {
+ return line.startsWith("Listening for transport dt_socket");
+ }
+
+ private static void checkForError(String line) {
+ if (line.contains("ERROR:")) {
+ error_seen++;
+ }
+ }
+
/*
* - pick a TCP port
* - Launch a server debuggee: server=y,suspend=y,address=${port}
@@ -146,15 +117,6 @@ public class RunToExit {
// launch the server debuggee
Process process = launch(address, "Exit0");
- // wait for the debugge to be ready
- while (!ready) {
- try {
- Thread.sleep(1000);
- } catch(Exception ee) {
- throw ee;
- }
- }
-
// attach to server debuggee and resume it so it can exit
AttachingConnector conn = (AttachingConnector)findConnector("com.sun.jdi.SocketAttach");
Map conn_args = conn.defaultArguments();
@@ -164,7 +126,16 @@ public class RunToExit {
System.out.println("Connection arguments: " + conn_args);
- VirtualMachine vm = conn.attach(conn_args);
+ VirtualMachine vm = null;
+ while (vm == null) {
+ try {
+ vm = conn.attach(conn_args);
+ } catch (ConnectException e) {
+ e.printStackTrace(System.out);
+ System.out.println("--- Debugee not ready. Retrying in 500ms. ---");
+ Thread.sleep(500);
+ }
+ }
// The first event is always a VMStartEvent, and it is always in
// an EventSet by itself. Wait for it.
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
index fedcd91f796..3e88f8887df 100644
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
@@ -88,24 +88,12 @@ public final class ProcessTools {
ProcessBuilder processBuilder,
Consumer consumer)
throws IOException {
- Process p = null;
try {
- p = startProcess(
- name,
- processBuilder,
- line -> {
- if (consumer != null) {
- consumer.accept(line);
- }
- return false;
- },
- -1,
- TimeUnit.NANOSECONDS
- );
+ return startProcess(name, processBuilder, consumer, null, -1, TimeUnit.NANOSECONDS);
} catch (InterruptedException | TimeoutException e) {
- // can't ever happen
+ // will never happen
+ throw new RuntimeException(e);
}
- return p;
}
/**
@@ -133,6 +121,38 @@ public final class ProcessTools {
final Predicate linePredicate,
long timeout,
TimeUnit unit)
+ throws IOException, InterruptedException, TimeoutException {
+ return startProcess(name, processBuilder, null, linePredicate, timeout, unit);
+ }
+
+ /**
+ * Starts a process from its builder.
+ * The default redirects of STDOUT and STDERR are started
+ *
+ * It is possible to wait for the process to get to a warmed-up state
+ * via {@linkplain Predicate} condition on the STDOUT and monitor the
+ * in-streams via the provided {@linkplain Consumer}
+ *
+ * @param name The process name
+ * @param processBuilder The process builder
+ * @param lineConsumer The {@linkplain Consumer} the lines will be forwarded to
+ * @param linePredicate The {@linkplain Predicate} to use on the STDOUT
+ * Used to determine the moment the target app is
+ * properly warmed-up.
+ * It can be null - in that case the warmup is skipped.
+ * @param timeout The timeout for the warmup waiting; -1 = no wait; 0 = wait forever
+ * @param unit The timeout {@linkplain TimeUnit}
+ * @return Returns the initialized {@linkplain Process}
+ * @throws IOException
+ * @throws InterruptedException
+ * @throws TimeoutException
+ */
+ public static Process startProcess(String name,
+ ProcessBuilder processBuilder,
+ final Consumer lineConsumer,
+ final Predicate linePredicate,
+ long timeout,
+ TimeUnit unit)
throws IOException, InterruptedException, TimeoutException {
System.out.println("["+name+"]:" + processBuilder.command().stream().collect(Collectors.joining(" ")));
Process p = processBuilder.start();
@@ -141,6 +161,18 @@ public final class ProcessTools {
stdout.addPump(new LineForwarder(name, System.out));
stderr.addPump(new LineForwarder(name, System.err));
+ if (lineConsumer != null) {
+ StreamPumper.LinePump pump = new StreamPumper.LinePump() {
+ @Override
+ protected void processLine(String line) {
+ lineConsumer.accept(line);
+ }
+ };
+ stdout.addPump(pump);
+ stderr.addPump(pump);
+ }
+
+
CountDownLatch latch = new CountDownLatch(1);
if (linePredicate != null) {
StreamPumper.LinePump pump = new StreamPumper.LinePump() {
From d24e1db13aa4871eded32742dc5a3536e6c49994 Mon Sep 17 00:00:00 2001
From: Alexander Kulyakhtin
Date: Wed, 11 Mar 2015 00:45:02 +0300
Subject: [PATCH 6/6] 8072754: com/sun/jdi/NativeInstanceFilter.java requires
adjustments to work with module boundaries
The tests uses sun.misc.Version to check if the JVM version is greater than a certain version. For the JDK 9 the condition is always true and the usage of sun.misc.Version thus can be eliminated.
Reviewed-by: alanb, sla
---
.../com/sun/jdi/NativeInstanceFilterTarg.java | 24 +++----------------
1 file changed, 3 insertions(+), 21 deletions(-)
diff --git a/jdk/test/com/sun/jdi/NativeInstanceFilterTarg.java b/jdk/test/com/sun/jdi/NativeInstanceFilterTarg.java
index a3179da7078..5b81fc8e0b1 100644
--- a/jdk/test/com/sun/jdi/NativeInstanceFilterTarg.java
+++ b/jdk/test/com/sun/jdi/NativeInstanceFilterTarg.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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
@@ -21,36 +21,18 @@
* questions.
*/
-import sun.misc.Version;
-
public class NativeInstanceFilterTarg {
public static void main(String args[]) {
- boolean runTest = jvmSupportsJVMTI_12x();
String s1 = "abc";
String s2 = "def";
latch(s1);
s1.intern();
- if (runTest) {
- s2.intern(); // this is the call that generates events that ought
- // to be filtered out.
- } else {
- System.out.println("Neutering test since JVMTI 1.2 not supported");
- }
+ s2.intern(); // this is the call that generates events that ought
+ // to be filtered out.
}
// Used by debugger to get an instance to filter with
public static String latch(String s) { return s; }
- public static boolean jvmSupportsJVMTI_12x() {
- // This fix requires the JVM to support JVMTI 1.2, which doesn't
- // happen until HSX 20.0, build 05.
- int major = Version.jvmMajorVersion();
- int minor = Version.jvmMinorVersion();
- int micro = Version.jvmMicroVersion();
- int build = Version.jvmBuildNumber();
-
- return (major > 20 || major == 20 &&
- (minor > 0 || micro > 0 || build >= 5));
- }
}