From 6325503100bd61491f21ed80b7a863931bcc7a28 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Thu, 4 Aug 2016 16:11:30 -0700 Subject: [PATCH 01/18] 8162670: make of jtreg_tests fails if no tests are run, causing jprt test runs to also fail Clear the jtreg exit code when set to 1. Reviewed-by: stsmirno, dholmes --- jdk/test/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/test/Makefile b/jdk/test/Makefile index 8f2038527a3..6958d9abb58 100644 --- a/jdk/test/Makefile +++ b/jdk/test/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -185,6 +185,9 @@ BUNDLE_UP_AND_EXIT = \ ( \ jtregExitCode=$$? && \ _summary="$(SUMMARY_TXT)"; \ + if [ $${jtregExitCode} = 1 ] ; then \ + jtregExitCode=0; \ + fi; \ $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \ $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \ if [ -r "$${_summary}" ] ; then \ From 6500bf0035617d7e38d7c7bc6070a256ae6646a6 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Mon, 8 Aug 2016 21:59:33 +0900 Subject: [PATCH 02/18] 8163272: jhsdb jinfo cannot show system properties Reviewed-by: dholmes, dsamersoff --- .../sun/tools/jhsdb/BasicLauncherTest.java | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java index 4125dbfb4d4..604b28241ee 100644 --- a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java +++ b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java @@ -40,6 +40,7 @@ import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Arrays; +import java.util.Optional; import jdk.testlibrary.JDKToolLauncher; import jdk.testlibrary.Utils; import jdk.testlibrary.OutputAnalyzer; @@ -111,7 +112,8 @@ public class BasicLauncherTest { * @param vmArgs - vm and java arguments to launch test app * @return exit code of tool */ - public static void launch(String expectedMessage, List toolArgs) + public static void launch(String expectedMessage, + Optional unexpectedMessage, List toolArgs) throws IOException { System.out.println("Starting LingeredApp"); @@ -131,6 +133,7 @@ public class BasicLauncherTest { processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT); OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);; output.shouldContain(expectedMessage); + unexpectedMessage.ifPresent(output::shouldNotContain); output.shouldHaveExitValue(0); } catch (Exception ex) { @@ -140,13 +143,16 @@ public class BasicLauncherTest { } } - public static void launch(String expectedMessage, String... toolArgs) + public static void launch(String expectedMessage, + String unexpectedMessage, String... toolArgs) throws IOException { - launch(expectedMessage, Arrays.asList(toolArgs)); + launch(expectedMessage, Optional.ofNullable(unexpectedMessage), + Arrays.asList(toolArgs)); } - public static void launchNotOSX(String expectedMessage, String... toolArgs) + public static void launchNotOSX(String expectedMessage, + String unexpectedMessage, String... toolArgs) throws IOException { if (Platform.isOSX()) { @@ -154,6 +160,8 @@ public class BasicLauncherTest { System.out.println("This test is not expected to work on OS X. Skipping"); return; } + + launch(expectedMessage, unexpectedMessage, toolArgs); } public static void testHeapDump() throws IOException { @@ -164,7 +172,7 @@ public class BasicLauncherTest { } dump.deleteOnExit(); - launch("heap written to", "jmap", + launch("heap written to", null, "jmap", "--binaryheap", "--dumpfile=" + dump.getAbsolutePath()); assertTrue(dump.exists() && dump.isFile(), @@ -182,11 +190,12 @@ public class BasicLauncherTest { launchCLHSDB(); - launch("compiler detected", "jmap", "--clstats"); - launchNotOSX("No deadlocks found", "jstack"); - launch("compiler detected", "jmap"); - launch("Java System Properties", "jinfo"); - launch("java.threads", "jsnap"); + launch("compiler detected", null, "jmap", "--clstats"); + launchNotOSX("No deadlocks found", null, "jstack"); + launch("compiler detected", null, "jmap"); + launch("Java System Properties", + "System Properties info not available", "jinfo"); + launch("java.threads", null, "jsnap"); testHeapDump(); From d928f3fae8448f7bcfe3e7859d945e216acbf4d6 Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Mon, 15 Aug 2016 23:45:32 +0300 Subject: [PATCH 03/18] 8163896: Finalizing one key of a KeyPair invalidates the other key Reviewed-by: coffeys, vinnie --- .../classes/sun/security/mscapi/Key.java | 64 +++++++------ .../classes/sun/security/mscapi/KeyStore.java | 6 +- .../sun/security/mscapi/RSAKeyPair.java | 7 +- .../sun/security/mscapi/RSAPrivateKey.java | 16 +++- .../sun/security/mscapi/RSAPublicKey.java | 20 +++-- .../KeyPairGenerator/FinalizeHalf.java | 90 +++++++++++++++++++ 6 files changed, 158 insertions(+), 45 deletions(-) create mode 100644 jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java diff --git a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/Key.java b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/Key.java index 0124ffb3a40..8154c489a95 100644 --- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/Key.java +++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/Key.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import sun.security.util.Length; /** * The handle for an RSA or DSA key using the Microsoft Crypto API. * - * @see DSAPrivateKey * @see RSAPrivateKey * @see RSAPublicKey * @@ -41,9 +40,35 @@ abstract class Key implements java.security.Key, Length { private static final long serialVersionUID = -1088859394025049194L; - // Native handle - protected long hCryptProv = 0; - protected long hCryptKey = 0; + static class NativeHandles { + long hCryptProv = 0; + long hCryptKey = 0; + + public NativeHandles(long hCryptProv, long hCryptKey) { + this.hCryptProv = hCryptProv; + this.hCryptKey = hCryptKey; + } + + /** + * Finalization method + */ + protected void finalize() throws Throwable + { + try { + synchronized(this) + { + cleanUp(hCryptProv, hCryptKey); + hCryptProv = 0; + hCryptKey = 0; + } + + } finally { + super.finalize(); + } + } + } + + protected NativeHandles handles; // Key length protected int keyLength = 0; @@ -51,31 +76,12 @@ abstract class Key implements java.security.Key, Length /** * Construct a Key object. */ - protected Key(long hCryptProv, long hCryptKey, int keyLength) + protected Key(NativeHandles handles, int keyLength) { - this.hCryptProv = hCryptProv; - this.hCryptKey = hCryptKey; + this.handles = handles; this.keyLength = keyLength; } - /** - * Finalization method - */ - protected void finalize() throws Throwable - { - try { - synchronized(this) - { - cleanUp(hCryptProv, hCryptKey); - hCryptProv = 0; - hCryptKey = 0; - } - - } finally { - super.finalize(); - } - } - /** * Native method to cleanup the key handle. */ @@ -96,7 +102,7 @@ abstract class Key implements java.security.Key, Length */ public long getHCryptKey() { - return hCryptKey; + return handles.hCryptKey; } /** @@ -104,12 +110,12 @@ abstract class Key implements java.security.Key, Length */ public long getHCryptProvider() { - return hCryptProv; + return handles.hCryptProv; } /** * Returns the standard algorithm name for this key. For - * example, "DSA" would indicate that this key is a DSA key. + * example, "RSA" would indicate that this key is a RSA key. * See Appendix A in the * Java Cryptography Architecture API Specification & Reference diff --git a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java index 84828c156bf..c4888bf3049 100644 --- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java +++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java @@ -168,7 +168,7 @@ abstract class KeyStore extends KeyStoreSpi { } certChain = chain; } - }; + } /* * An X.509 certificate factory. @@ -798,7 +798,8 @@ abstract class KeyStore extends KeyStoreSpi { } storeWithUniqueAlias(alias, new KeyEntry(alias, - new RSAPrivateKey(hCryptProv, hCryptKey, keyLength), + new RSAPrivateKey(new Key.NativeHandles(hCryptProv, + hCryptKey), keyLength), certChain)); } catch (Throwable e) @@ -854,7 +855,6 @@ abstract class KeyStore extends KeyStoreSpi { * Load keys and/or certificates from keystore into Collection. * * @param name Name of keystore. - * @param entries Collection of key/certificate. */ private native void loadKeysOrCertificateChains(String name) throws KeyStoreException; diff --git a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPair.java b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPair.java index 6fba2a23cd8..0880c20d85d 100644 --- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPair.java +++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPair.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,8 +41,9 @@ class RSAKeyPair { */ RSAKeyPair(long hCryptProv, long hCryptKey, int keyLength) { - privateKey = new RSAPrivateKey(hCryptProv, hCryptKey, keyLength); - publicKey = new RSAPublicKey(hCryptProv, hCryptKey, keyLength); + Key.NativeHandles handles = new Key.NativeHandles(hCryptProv, hCryptKey); + privateKey = new RSAPrivateKey(handles, keyLength); + publicKey = new RSAPublicKey(handles, keyLength); } public RSAPrivateKey getPrivate() { diff --git a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPrivateKey.java b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPrivateKey.java index bc530f5372b..ca692dfa2f3 100644 --- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPrivateKey.java +++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPrivateKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,15 @@ class RSAPrivateKey extends Key implements PrivateKey */ RSAPrivateKey(long hCryptProv, long hCryptKey, int keyLength) { - super(hCryptProv, hCryptKey, keyLength); + super(new NativeHandles(hCryptProv, hCryptKey), keyLength); + } + + /** + * Construct an RSAPrivateKey object. + */ + RSAPrivateKey(NativeHandles handles, int keyLength) + { + super(handles, keyLength); } /** @@ -63,8 +71,8 @@ class RSAPrivateKey extends Key implements PrivateKey public String toString() { return "RSAPrivateKey [size=" + keyLength + " bits, type=" + - getKeyType(hCryptKey) + ", container=" + - getContainerName(hCryptProv) + "]"; + getKeyType(handles.hCryptKey) + ", container=" + + getContainerName(handles.hCryptProv) + "]"; } // This class is not serializable diff --git a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPublicKey.java b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPublicKey.java index a62d783aa7c..52081abb5aa 100644 --- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPublicKey.java +++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPublicKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,15 @@ class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey */ RSAPublicKey(long hCryptProv, long hCryptKey, int keyLength) { - super(hCryptProv, hCryptKey, keyLength); + super(new NativeHandles(hCryptProv, hCryptKey), keyLength); + } + + /** + * Construct an RSAPublicKey object. + */ + RSAPublicKey(NativeHandles handles, int keyLength) + { + super(handles, keyLength); } /** @@ -77,8 +85,8 @@ class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey StringBuffer sb = new StringBuffer(); sb.append("RSAPublicKey [size=").append(keyLength) - .append(" bits, type=").append(getKeyType(hCryptKey)) - .append(", container=").append(getContainerName(hCryptProv)) + .append(" bits, type=").append(getKeyType(handles.hCryptKey)) + .append(", container=").append(getContainerName(handles.hCryptProv)) .append("]\n modulus: ").append(getModulus()) .append("\n public exponent: ").append(getPublicExponent()); @@ -93,7 +101,7 @@ class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey if (exponent == null) { try { - publicKeyBlob = getPublicKeyBlob(hCryptKey); + publicKeyBlob = getPublicKeyBlob(handles.hCryptKey); exponent = new BigInteger(1, getExponent(publicKeyBlob)); } catch (KeyException e) { @@ -112,7 +120,7 @@ class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey if (modulus == null) { try { - publicKeyBlob = getPublicKeyBlob(hCryptKey); + publicKeyBlob = getPublicKeyBlob(handles.hCryptKey); modulus = new BigInteger(1, getModulus(publicKeyBlob)); } catch (KeyException e) { diff --git a/jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java b/jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java new file mode 100644 index 00000000000..a2a1eb36194 --- /dev/null +++ b/jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8163896 + * @summary Finalizing one key of a KeyPair invalidates the other key + */ + +import java.security.Key; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.ProviderException; +import java.security.Security; +import java.util.function.Consumer; +import java.util.ArrayList; +import java.util.List; + +public class FinalizeHalf { + + static int failures = 0; + + public static void main(String[] args) throws Throwable { + List> methods = new ArrayList<>(); + methods.add((Key k) -> k.getEncoded()); + methods.add((Key k) -> k.toString()); + + for (String algo : new String[] {"DiffieHellman", "DSA", "RSA"}) { + for (Provider provider : Security.getProviders()) { + for (boolean priv : new boolean[] {true, false}) { + for (Consumer method : methods) { + test(algo, provider, priv, method); + } + } + } + } + + if (failures > 0) { + throw new RuntimeException(failures + " test(s) failed."); + } + } + + static void test(String algo, Provider provider, boolean priv, + Consumer method) throws Exception { + KeyPairGenerator generator; + try { + generator = KeyPairGenerator.getInstance(algo, provider); + } catch (NoSuchAlgorithmException nsae) { + return; + } + + System.out.println("Checking " + provider.getName() + ", " + algo); + + KeyPair pair = generator.generateKeyPair(); + Key key = priv ? pair.getPrivate() : pair.getPublic(); + + pair = null; + for (int i = 0; i < 32; ++i) { + System.gc(); + } + + try { + method.accept(key); + } catch (ProviderException pe) { + failures++; + } + } +} From aacb739bbd84177a1a5272d32a5524e7205a2b24 Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Mon, 15 Aug 2016 16:32:41 -0700 Subject: [PATCH 04/18] 8162484: javax/net/ssl/Stapling/SSLSocketWithStapling.java test fails intermittently with "Address already in use" error Reviewed-by: xuelei, jnimeh --- .../testlibrary/SimpleOCSPServer.java | 45 +++++++++--- .../ssl/Stapling/SSLSocketWithStapling.java | 72 ++++++++----------- 2 files changed, 67 insertions(+), 50 deletions(-) diff --git a/jdk/test/java/security/testlibrary/SimpleOCSPServer.java b/jdk/test/java/security/testlibrary/SimpleOCSPServer.java index 77b8bb44642..4901e6f2651 100644 --- a/jdk/test/java/security/testlibrary/SimpleOCSPServer.java +++ b/jdk/test/java/security/testlibrary/SimpleOCSPServer.java @@ -64,6 +64,8 @@ public class SimpleOCSPServer { private static final SimpleDateFormat utcDateFmt = new SimpleDateFormat("MMM dd yyyy, HH:mm:ss z"); + static final int FREE_PORT = 0; + // CertStatus values public static enum CertStatus { CERT_STATUS_GOOD, @@ -88,7 +90,8 @@ public class SimpleOCSPServer { private volatile boolean started = false; private volatile boolean serverReady = false; private volatile boolean receivedShutdown = false; - private long delayMsec = 0; + private volatile boolean acceptConnections = true; + private volatile long delayMsec = 0; // Fields used in the generation of responses private long nextUpdateInterval = -1; @@ -116,7 +119,7 @@ public class SimpleOCSPServer { */ public SimpleOCSPServer(KeyStore ks, String password, String issuerAlias, String signerAlias) throws GeneralSecurityException, IOException { - this(null, 0, ks, password, issuerAlias, signerAlias); + this(null, FREE_PORT, ks, password, issuerAlias, signerAlias); } /** @@ -230,6 +233,15 @@ public class SimpleOCSPServer { while (!receivedShutdown) { try { Socket newConnection = servSocket.accept(); + if (!acceptConnections) { + try { + log("Reject connection"); + newConnection.close(); + } catch (IOException e) { + // ignore + } + continue; + } threadPool.submit(new OcspHandler(newConnection)); } catch (SocketTimeoutException timeout) { // Nothing to do here. If receivedShutdown @@ -256,6 +268,23 @@ public class SimpleOCSPServer { }); } + /** + * Make the OCSP server reject incoming connections. + */ + public synchronized void rejectConnections() { + log("Reject OCSP connections"); + acceptConnections = false; + } + + /** + * Make the OCSP server accept incoming connections. + */ + public synchronized void acceptConnections() { + log("Accept OCSP connections"); + acceptConnections = true; + } + + /** * Stop the OCSP server. */ @@ -499,13 +528,11 @@ public class SimpleOCSPServer { * on the incoming request. */ public void setDelay(long delayMillis) { - if (!started) { - delayMsec = delayMillis > 0 ? delayMillis : 0; - if (delayMsec > 0) { - log("OCSP latency set to " + delayMsec + " milliseconds."); - } else { - log("OCSP latency disabled"); - } + delayMsec = delayMillis > 0 ? delayMillis : 0; + if (delayMsec > 0) { + log("OCSP latency set to " + delayMsec + " milliseconds."); + } else { + log("OCSP latency disabled"); } } diff --git a/jdk/test/javax/net/ssl/Stapling/SSLSocketWithStapling.java b/jdk/test/javax/net/ssl/Stapling/SSLSocketWithStapling.java index f1e5f1da945..aaa8ce35396 100644 --- a/jdk/test/javax/net/ssl/Stapling/SSLSocketWithStapling.java +++ b/jdk/test/javax/net/ssl/Stapling/SSLSocketWithStapling.java @@ -119,20 +119,22 @@ public class SSLSocketWithStapling { System.setProperty("javax.net.debug", "ssl"); } - // Create the PKI we will use for the test and start the OCSP servers - createPKI(); + try { + // Create the PKI we will use for the test and start the OCSP servers + createPKI(); - testAllDefault(); - testPKIXParametersRevEnabled(); - testRevokedCertificate(); - testHardFailFallback(); - testSoftFailFallback(); - testLatencyNoStaple(false); - testLatencyNoStaple(true); - - // shut down the OCSP responders before finishing the test - intOcsp.stop(); - rootOcsp.stop(); + testAllDefault(); + testPKIXParametersRevEnabled(); + testRevokedCertificate(); + testHardFailFallback(); + testSoftFailFallback(); + testLatencyNoStaple(false); + testLatencyNoStaple(true); + } finally { + // shut down the OCSP responders before finishing the test + intOcsp.stop(); + rootOcsp.stop(); + } } /** @@ -281,11 +283,9 @@ public class SSLSocketWithStapling { ServerParameters servParams = new ServerParameters(); serverReady = false; - // Stop the OCSP responders and give a 1 second delay before - // running the test. - intOcsp.stop(); - rootOcsp.stop(); - Thread.sleep(1000); + // make OCSP responders reject connections + intOcsp.rejectConnections(); + rootOcsp.rejectConnections(); System.out.println("======================================="); System.out.println("Stapling enbled in client and server,"); @@ -315,9 +315,9 @@ public class SSLSocketWithStapling { System.out.println(" PASS"); System.out.println("=======================================\n"); - // Start the OCSP responders up again - intOcsp.start(); - rootOcsp.start(); + // Make OCSP responders accept connections + intOcsp.acceptConnections(); + rootOcsp.acceptConnections(); // Wait 5 seconds for server ready for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) { @@ -338,11 +338,9 @@ public class SSLSocketWithStapling { ServerParameters servParams = new ServerParameters(); serverReady = false; - // Stop the OCSP responders and give a 1 second delay before - // running the test. - intOcsp.stop(); - rootOcsp.stop(); - Thread.sleep(1000); + // make OCSP responders reject connections + intOcsp.rejectConnections(); + rootOcsp.rejectConnections(); System.out.println("======================================="); System.out.println("Stapling enbled in client and server,"); @@ -372,9 +370,9 @@ public class SSLSocketWithStapling { System.out.println(" PASS"); System.out.println("=======================================\n"); - // Start the OCSP responders up again - intOcsp.start(); - rootOcsp.start(); + // Make OCSP responders accept connections + intOcsp.acceptConnections(); + rootOcsp.acceptConnections(); // Wait 5 seconds for server ready for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) { @@ -401,15 +399,10 @@ public class SSLSocketWithStapling { ServerParameters servParams = new ServerParameters(); serverReady = false; - // Stop the OCSP responders and give a 1 second delay before - // running the test. - intOcsp.stop(); - rootOcsp.stop(); - Thread.sleep(1000); + // Give a 1 second delay before running the test. intOcsp.setDelay(3000); rootOcsp.setDelay(3000); - rootOcsp.start(); - intOcsp.start(); + Thread.sleep(1000); // Wait 5 seconds for server ready for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) { @@ -458,13 +451,9 @@ public class SSLSocketWithStapling { System.out.println("========================================\n"); // Remove the OCSP responder latency - intOcsp.stop(); - rootOcsp.stop(); - Thread.sleep(1000); intOcsp.setDelay(0); rootOcsp.setDelay(0); - rootOcsp.start(); - intOcsp.start(); + Thread.sleep(1000); // Wait 5 seconds for server ready for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) { @@ -676,6 +665,7 @@ public class SSLSocketWithStapling { * Release the client, if not active already... */ System.err.println("Server died..."); + e.printStackTrace(System.err); serverReady = true; serverException = e; } From 10179e0d9b6790ad5a359ded699985f52025e170 Mon Sep 17 00:00:00 2001 From: Nishit Jain Date: Tue, 16 Aug 2016 15:26:41 +0900 Subject: [PATCH 05/18] 8129555: DateFormatSymbols: month-related methods must refer to Calendar constants Reviewed-by: naoto, okutsu, peytoia --- .../classes/java/text/DateFormatSymbols.java | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java index 5284bcd3907..0c9b50ae152 100644 --- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java +++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java @@ -399,7 +399,10 @@ public class DateFormatSymbols implements Serializable, Cloneable { * Calendar Elements in the Unicode Locale Data Markup Language * (LDML) specification for more details. * - * @return the month strings. + * @return the month strings. Use + * {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, + * etc. to index the result array. */ public String[] getMonths() { return Arrays.copyOf(months, months.length); @@ -407,7 +410,9 @@ public class DateFormatSymbols implements Serializable, Cloneable { /** * Sets month strings. For example: "January", "February", etc. - * @param newMonths the new month strings. + * @param newMonths the new month strings. The array should + * be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc. */ public void setMonths(String[] newMonths) { months = Arrays.copyOf(newMonths, newMonths.length); @@ -427,7 +432,10 @@ public class DateFormatSymbols implements Serializable, Cloneable { * Calendar Elements in the Unicode Locale Data Markup Language * (LDML) specification for more details. * - * @return the short month strings. + * @return the short month strings. Use + * {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, + * etc. to index the result array. */ public String[] getShortMonths() { return Arrays.copyOf(shortMonths, shortMonths.length); @@ -435,7 +443,9 @@ public class DateFormatSymbols implements Serializable, Cloneable { /** * Sets short month strings. For example: "Jan", "Feb", etc. - * @param newShortMonths the new short month strings. + * @param newShortMonths the new short month strings. The array should + * be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc. */ public void setShortMonths(String[] newShortMonths) { shortMonths = Arrays.copyOf(newShortMonths, newShortMonths.length); @@ -444,8 +454,10 @@ public class DateFormatSymbols implements Serializable, Cloneable { /** * Gets weekday strings. For example: "Sunday", "Monday", etc. - * @return the weekday strings. Use Calendar.SUNDAY, - * Calendar.MONDAY, etc. to index the result array. + * @return the weekday strings. Use + * {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index + * the result array. */ public String[] getWeekdays() { return Arrays.copyOf(weekdays, weekdays.length); @@ -454,8 +466,8 @@ public class DateFormatSymbols implements Serializable, Cloneable { /** * Sets weekday strings. For example: "Sunday", "Monday", etc. * @param newWeekdays the new weekday strings. The array should - * be indexed by Calendar.SUNDAY, - * Calendar.MONDAY, etc. + * be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. */ public void setWeekdays(String[] newWeekdays) { weekdays = Arrays.copyOf(newWeekdays, newWeekdays.length); @@ -464,8 +476,10 @@ public class DateFormatSymbols implements Serializable, Cloneable { /** * Gets short weekday strings. For example: "Sun", "Mon", etc. - * @return the short weekday strings. Use Calendar.SUNDAY, - * Calendar.MONDAY, etc. to index the result array. + * @return the short weekday strings. Use + * {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index + * the result array. */ public String[] getShortWeekdays() { return Arrays.copyOf(shortWeekdays, shortWeekdays.length); @@ -474,8 +488,8 @@ public class DateFormatSymbols implements Serializable, Cloneable { /** * Sets short weekday strings. For example: "Sun", "Mon", etc. * @param newShortWeekdays the new short weekday strings. The array should - * be indexed by Calendar.SUNDAY, - * Calendar.MONDAY, etc. + * be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. */ public void setShortWeekdays(String[] newShortWeekdays) { shortWeekdays = Arrays.copyOf(newShortWeekdays, newShortWeekdays.length); From ca2024b93f9d364910e71e238268db0f558e25d1 Mon Sep 17 00:00:00 2001 From: Sibabrata Sahoo Date: Tue, 16 Aug 2016 12:34:00 +0530 Subject: [PATCH 06/18] 8159964: Update Tests to verify JDK build for "JDK-8159488 Deprivilege java.xml.crypto" Reviewed-by: valeriep --- .../DeprivilegedModuleLoaderTest.java | 90 +++++++++++++++++++ .../dsig/TransformService/NullParent.java | 1 + .../crypto/dsig/TransformService/test.policy | 3 + .../crypto/dsig/keyinfo/KeyInfo/Marshal.java | 2 +- .../crypto/dsig/keyinfo/KeyInfo/test.policy | 3 + 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/security/Security/ClassLoader/DeprivilegedModuleLoaderTest.java create mode 100644 jdk/test/javax/xml/crypto/dsig/TransformService/test.policy create mode 100644 jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/test.policy diff --git a/jdk/test/java/security/Security/ClassLoader/DeprivilegedModuleLoaderTest.java b/jdk/test/java/security/Security/ClassLoader/DeprivilegedModuleLoaderTest.java new file mode 100644 index 00000000000..b12259b6833 --- /dev/null +++ b/jdk/test/java/security/Security/ClassLoader/DeprivilegedModuleLoaderTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import javax.security.auth.kerberos.KeyTab; +import javax.xml.crypto.KeySelectorException; +import javax.xml.crypto.dsig.XMLSignatureFactory; +import com.sun.security.auth.callback.TextCallbackHandler; +import com.sun.security.jgss.AuthorizationDataEntry; + +/* + * @test + * @bug 8159964 + * @summary Classes from deprivileged modules should get loaded through + * Platform Classloader. + * @run main DeprivilegedModuleLoaderTest + */ +public class DeprivilegedModuleLoaderTest { + + public static void main(String[] args) { + + boolean pass = true; + List> classes = getDeprivilegedClasses(); + for (Class cls : classes) { + try { + pass &= testPlatformClassLoader(cls); + } catch (Exception exc) { + exc.printStackTrace(System.out); + pass = false; + } + } + + if (!pass) { + throw new RuntimeException("Atleast one test failed."); + } + } + + private static List> getDeprivilegedClasses() { + + List> classes = new ArrayList>(); + // Test from java.xml.crypto/javax/xml/crypto/dsig package + classes.add(XMLSignatureFactory.class); + // Test from java.xml.crypto/javax/xml/crypto package + classes.add(KeySelectorException.class); + // Test From java.security.jgss/javax/security/auth/kerberos package + classes.add(KeyTab.class); + // Test from jdk.security.jgss/com/sun/security/jgss package + classes.add(AuthorizationDataEntry.class); + // Test from jdk.security.auth/com/sun/security/auth/callback package + classes.add(TextCallbackHandler.class); + return classes; + } + + private static boolean testPlatformClassLoader(Class cls) { + + ClassLoader loader = cls.getClassLoader(); + if (loader == null) { + throw new RuntimeException(String.format( + "Loaded through Bootstrap Classloader: '%s'", cls)); + } else if (!loader.toString().contains("PlatformClassLoader")) { + throw new RuntimeException(String.format( + "Not loaded through Platform ClassLoader: '%s'", cls)); + } + System.out.println(String.format( + "Pass: '%s' get loaded through PlatformClassLoader", cls)); + return true; + } +} diff --git a/jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java b/jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java index 79c03174d20..1205cce8beb 100644 --- a/jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java +++ b/jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java @@ -26,6 +26,7 @@ * @bug 8022120 * @summary check that the init and marshalParams methods throw * NullPointerException when the parent parameter is null + * @run main/othervm/java.security.policy==test.policy NullParent */ import javax.xml.crypto.dsig.CanonicalizationMethod; diff --git a/jdk/test/javax/xml/crypto/dsig/TransformService/test.policy b/jdk/test/javax/xml/crypto/dsig/TransformService/test.policy new file mode 100644 index 00000000000..ccc41e5f1ab --- /dev/null +++ b/jdk/test/javax/xml/crypto/dsig/TransformService/test.policy @@ -0,0 +1,3 @@ +grant { + +}; diff --git a/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/Marshal.java b/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/Marshal.java index f03cbf3ac99..159fc4ef627 100644 --- a/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/Marshal.java +++ b/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/Marshal.java @@ -27,7 +27,7 @@ * @summary Test that KeyInfo.marshal works correctly * @modules java.xml.crypto/org.jcp.xml.dsig.internal.dom * @compile -XDignore.symbol.file Marshal.java - * @run main Marshal + * @run main/othervm/java.security.policy==test.policy Marshal * @author Sean Mullan */ diff --git a/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/test.policy b/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/test.policy new file mode 100644 index 00000000000..a6a4709bbae --- /dev/null +++ b/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/test.policy @@ -0,0 +1,3 @@ +grant { + permission java.lang.RuntimePermission "accessClassInPackage.org.jcp.xml.dsig.internal.dom"; +}; From 68ec99774eac5730e53b3b3fd2f850c57b1b130f Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 16 Aug 2016 21:28:10 +0800 Subject: [PATCH 07/18] 8141411: keytool can wrongly parse the start date value given by the -startdate option Reviewed-by: xuelei --- .../sun/security/tools/keytool/Main.java | 4 +- .../security/tools/keytool/StartDateTest.java | 37 +++++++++++++------ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java index 12b5041ea41..6e26cc62128 100644 --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -3631,8 +3631,8 @@ public final class Main { if (time != null) { if (time.matches("\\d\\d:\\d\\d:\\d\\d")) { c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(time.substring(0, 2))); - c.set(Calendar.MINUTE, Integer.valueOf(time.substring(0, 2))); - c.set(Calendar.SECOND, Integer.valueOf(time.substring(0, 2))); + c.set(Calendar.MINUTE, Integer.valueOf(time.substring(3, 5))); + c.set(Calendar.SECOND, Integer.valueOf(time.substring(6, 8))); c.set(Calendar.MILLISECOND, 0); } else { throw ioe; diff --git a/jdk/test/sun/security/tools/keytool/StartDateTest.java b/jdk/test/sun/security/tools/keytool/StartDateTest.java index a1180eac4f2..d558ff6a49f 100644 --- a/jdk/test/sun/security/tools/keytool/StartDateTest.java +++ b/jdk/test/sun/security/tools/keytool/StartDateTest.java @@ -49,23 +49,31 @@ public class StartDateTest { new File("jks").delete(); - run("-keystore jks -storetype jks -storepass changeit -keypass changeit -alias me " + - "-keyalg rsa -genkeypair -dname CN=Haha -startdate +1y"); - cal.setTime(getIssueDate()); + run("one", "+1y"); + cal.setTime(getIssueDate("one")); System.out.println(cal); if (cal.get(Calendar.YEAR) != year + 1) { throw new Exception("Function check #1 fails"); } - run("-keystore jks -storetype jks -storepass changeit -keypass changeit -alias me " + - "-selfcert -startdate +1m"); - cal.setTime(getIssueDate()); + run("two", "+1m"); + cal.setTime(getIssueDate("two")); System.out.println(cal); if (cal.get(Calendar.MONTH) != (month + 1) % 12) { throw new Exception("Function check #2 fails"); } - new File("jks").delete(); + run("three", "2009/10/11 12:34:56"); + cal.setTime(getIssueDate("three")); + System.out.println(cal); + if (cal.get(Calendar.YEAR) != 2009 || + cal.get(Calendar.MONTH) != Calendar.OCTOBER || + cal.get(Calendar.DAY_OF_MONTH) != 11 || + cal.get(Calendar.HOUR_OF_DAY) != 12 || + cal.get(Calendar.MINUTE) != 34 || + cal.get(Calendar.SECOND) != 56) { + throw new Exception("Function check #3 fails"); + } // Part 2: Test format Method m = sun.security.tools.keytool.Main.class.getDeclaredMethod( @@ -129,16 +137,23 @@ public class StartDateTest { } } - static void run(String s) throws Exception { - sun.security.tools.keytool.Main.main((s+" -debug").split(" ")); + // The keytool command line template, alias and startdate TBD + static String[] cmd = ("-alias tbd -startdate tbd -keystore jks " + + "-storetype jks -storepass changeit -keypass changeit " + + "-keyalg rsa -genkeypair -dname CN=Haha -debug").split(" "); + + static void run(String alias, String startDate) throws Exception { + cmd[1] = alias; + cmd[3] = startDate; + sun.security.tools.keytool.Main.main(cmd); } - static Date getIssueDate() throws Exception { + static Date getIssueDate(String alias) throws Exception { KeyStore ks = KeyStore.getInstance("jks"); try (FileInputStream fis = new FileInputStream("jks")) { ks.load(fis, "changeit".toCharArray()); } - X509Certificate cert = (X509Certificate)ks.getCertificate("me"); + X509Certificate cert = (X509Certificate)ks.getCertificate(alias); return cert.getNotBefore(); } } From 8b6f2f072305e95fb217c964ee66cebb6537e4c9 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 17 Aug 2016 10:08:18 +0800 Subject: [PATCH 08/18] 8087144: sun/security/krb5/auto/MaxRetries.java fails with Retry count is -1 less 8153146: sun/security/krb5/auto/MaxRetries.java failed with timeout Reviewed-by: xuelei --- .../sun/security/krb5/auto/CommMatcher.java | 86 +++++++++++ .../sun/security/krb5/auto/MaxRetries.java | 133 +++++++++++++----- 2 files changed, 184 insertions(+), 35 deletions(-) create mode 100644 jdk/test/sun/security/krb5/auto/CommMatcher.java diff --git a/jdk/test/sun/security/krb5/auto/CommMatcher.java b/jdk/test/sun/security/krb5/auto/CommMatcher.java new file mode 100644 index 00000000000..1cfe25a5d4d --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/CommMatcher.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Matches the krb5 debug output: + * >>> KDCCommunication: kdc=host UDP:11555, timeout=100,Attempt =1, #bytes=138 + * + * Example: + * CommMatcher cm = new CommMatcher(); + * cm.addPort(12345).addPort(23456); + * for (String line : debugOutput) { + * if (cm.match(line)) { + * println("KDC: %c, %s, Timeout: %d\n", + * cm.kdc(), cm.protocol(), cm.timeout()); + * } + * } + */ +public class CommMatcher { + + static final Pattern re = Pattern.compile( + ">>> KDCCommunication: kdc=\\S+ (TCP|UDP):(\\d+), " + + "timeout=(\\d+),Attempt\\s*=(\\d+)"); + + List kdcPorts = new ArrayList<>(); + Matcher matcher; + + /** + * Add KDC ports one by one. The 1st KDC will be 'a' in {@link #kdc()}, + * 2nd is 'b', etc, etc. + */ + public CommMatcher addPort(int port) { + if (port > 0) { + kdcPorts.add(port); + } else { + kdcPorts.clear(); + } + return this; + } + + public boolean match(String line) { + matcher = re.matcher(line); + return matcher.find(); + } + + public String protocol() { + return matcher.group(1); + } + + public char kdc() { + int port = Integer.parseInt(matcher.group(2)); + return (char)(kdcPorts.indexOf(port) + 'a'); + } + + public int timeout() { + return BadKdc.toSymbolicSec(Integer.parseInt(matcher.group(3))); + } + + public int attempt() { + return Integer.parseInt(matcher.group(4)); + } +} diff --git a/jdk/test/sun/security/krb5/auto/MaxRetries.java b/jdk/test/sun/security/krb5/auto/MaxRetries.java index d23cd1043b5..b732becd169 100644 --- a/jdk/test/sun/security/krb5/auto/MaxRetries.java +++ b/jdk/test/sun/security/krb5/auto/MaxRetries.java @@ -30,6 +30,7 @@ * @summary support max_retries in krb5.conf */ +import javax.security.auth.login.LoginException; import java.io.*; import java.net.DatagramSocket; import java.security.Security; @@ -37,46 +38,86 @@ import java.security.Security; public class MaxRetries { static int idlePort = -1; + static CommMatcher cm = new CommMatcher(); public static void main(String[] args) throws Exception { System.setProperty("sun.security.krb5.debug", "true"); - new OneKDC(null).writeJAASConf(); + OneKDC kdc = new OneKDC(null).writeJAASConf(); // An idle UDP socket to prevent PortUnreachableException DatagramSocket ds = new DatagramSocket(); idlePort = ds.getLocalPort(); + cm.addPort(idlePort); + cm.addPort(kdc.getPort()); + System.setProperty("java.security.krb5.conf", "alternative-krb5.conf"); - // For tryLast Security.setProperty("krb5.kdc.bad.policy", "trylast"); + + // We always make the real timeout to be 1 second + BadKdc.setRatio(0.25f); rewriteMaxRetries(4); - test1(4000, 6); // 1 1 1 1 2 2 - test1(4000, 2); // 2 2 + // Explanation: In this case, max_retries=4 and timeout=4s. + // For AS-REQ without preauth, we will see 4 4s timeout on kdc#1 + // ("a4" repeat 4 times), and one 4s timeout on kdc#2 ("b4"). For + // AS-REQ with preauth, one 4s timeout on kdc#2 (second "b4"). + // we tolerate 4 real timeout on kdc#2, so make it "(b4){2,6}". + test1("a4a4a4a4b4b4", "a4a4a4a4(b4){2,6}"); + test1("b4b4", "(b4){2,6}"); + + BadKdc.setRatio(1f); rewriteMaxRetries(1); - test1(1000, 3); // 1 2 2 - test1(1000, 2); // 2 2 + // Explanation: Since max_retries=1 only, we could fail in 1st or 2nd + // AS-REQ to kdc#2. + String actual = test1("a1b1b1", "(a1b1b1|a1b1x|a1b1b1x)"); + if (actual.endsWith("x")) { + // If 1st attempt fails, all bads are back available + test1("a1b1b1", "(a1b1b1|a1b1x|a1b1b1x)"); + } else { + test1("b1b1", "(b1b1|b1x|b1b1x)"); + } + BadKdc.setRatio(0.2f); rewriteMaxRetries(-1); - test1(5000, 4); // 1 1 2 2 - test1(5000, 2); // 2 2 + test1("a5a5a5b5b5", "a5a5a5(b5){2,4}"); + test1("b5b5", "(b5){2,4}"); - // For tryLess - Security.setProperty("krb5.kdc.bad.policy", "tryless:1," + BadKdc.toReal(5000)); + BadKdc.setRatio(0.25f); + Security.setProperty("krb5.kdc.bad.policy", + "tryless:1,1000"); rewriteMaxRetries(4); - test1(4000, 7); // 1 1 1 1 2 1 2 - test1(4000, 4); // 1 2 1 2 + test1("a4a4a4a4b4a4b4", "a4a4a4a4(b4){1,3}a4(b4){1,3}"); + test1("a4b4a4b4", "a4(b4){1,3}a4(b4){1,3}"); + BadKdc.setRatio(1f); rewriteMaxRetries(1); - test1(1000, 4); // 1 2 1 2 - test1(1000, 4); // 1 2 1 2 + actual = test1("a1b1a1b1", "(a1b1|a1b1x|a1b1a1b1|a1b1a1b1x)"); + if (actual.endsWith("x")) { + test1("a1b1a1b1", "(a1b1|a1b1x|a1b1a1b1|a1b1a1b1x)"); + } else { + test1("a1b1a1b1", "(a1b1|a1b1x|a1b1a1b1|a1b1a1b1x)"); + } + BadKdc.setRatio(.2f); rewriteMaxRetries(-1); - test1(5000, 5); // 1 1 2 1 2 - test1(5000, 4); // 1 2 1 2 + test1("a5a5a5b5a5b5", "a5a5a5(b5){1,2}a5(b5){1,2}"); + test1("a5b5a5b5", "a5(b5){1,2}a5(b5){1,2}"); + + BadKdc.setRatio(1f); + rewriteMaxRetries(2); + if (BadKdc.toReal(2000) > 1000) { + // Explanation: if timeout is longer than 1s in tryLess, + // we will see "a1" at 2nd kdc#1 access + test1("a2a2b2a1b2", "a2a2(b2){1,2}a1(b2){1,2}"); + } else { + test1("a2a2b2a2b2", "a2a2(b2){1,2}a2(b2){1,2}"); + } + + BadKdc.setRatio(1f); rewriteUdpPrefLimit(-1, -1); // default, no limit test2("UDP"); @@ -95,32 +136,52 @@ public class MaxRetries { /** * One round of test for max_retries and timeout. - * @param timeout the expected timeout - * @param count the expected total try + * + * @param exact the expected exact match, where no timeout + * happens for real KDCs + * @param relaxed the expected relaxed match, where some timeout + * could happen for real KDCs + * @return the actual result */ - private static void test1(int timeout, int count) throws Exception { - String timeoutTag = "timeout=" + BadKdc.toReal(timeout); + private static String test1(String exact, String relaxed) throws Exception { ByteArrayOutputStream bo = new ByteArrayOutputStream(); PrintStream oldout = System.out; System.setOut(new PrintStream(bo)); - Context c = Context.fromJAAS("client"); + boolean failed = false; + long start = System.nanoTime(); + try { + Context c = Context.fromJAAS("client"); + } catch (LoginException e) { + failed = true; + } System.setOut(oldout); String[] lines = new String(bo.toByteArray()).split("\n"); - System.out.println("----------------- TEST (" + timeout + "," + - count + ") -----------------"); + System.out.println("----------------- TEST (" + exact + + ") -----------------"); + + // Result, a series of timeout + kdc# + StringBuilder sb = new StringBuilder(); for (String line: lines) { - if (line.startsWith(">>> KDCCommunication")) { + if (cm.match(line)) { System.out.println(line); - if (line.indexOf(timeoutTag) < 0) { - throw new Exception("Wrong timeout value" + timeoutTag); - } - count--; + sb.append(cm.kdc()).append(cm.timeout()); } } - if (count != 0) { - throw new Exception("Retry count is " + count + " less"); + if (failed) { + sb.append("x"); } + System.out.println("Time: " + (System.nanoTime() - start) / 1000000000d); + String actual = sb.toString(); + System.out.println("Actual: " + actual); + if (actual.equals(exact)) { + System.out.println("Exact match: " + exact); + } else if (actual.matches(relaxed)) { + System.out.println("!!!! Tolerant match: " + relaxed); + } else { + throw new Exception("Match neither " + exact + " nor " + relaxed); + } + return actual; } /** @@ -138,11 +199,11 @@ public class MaxRetries { String[] lines = new String(bo.toByteArray()).split("\n"); System.out.println("----------------- TEST -----------------"); for (String line: lines) { - if (line.startsWith(">>> KDCCommunication")) { + if (cm.match(line)) { System.out.println(line); count--; - if (line.indexOf(proto) < 0) { - throw new Exception("Wrong timeout value"); + if (!cm.protocol().equals(proto)) { + throw new Exception("Wrong protocol value"); } } } @@ -165,6 +226,7 @@ public class MaxRetries { } if (s.startsWith("[realms]")) { // Reconfig global setting + fw.write("kdc_timeout = 5000\n"); if (global != -1) { fw.write("udp_preference_limit = " + global + "\n"); } @@ -183,7 +245,8 @@ public class MaxRetries { /** * Set max_retries and timeout value for realm. The global value is always - * 2 and 5000. + * 3 and 5000. + * * @param value max_retries and timeout/1000 for a realm, -1 means none. */ private static void rewriteMaxRetries(int value) throws Exception { @@ -196,7 +259,7 @@ public class MaxRetries { } if (s.startsWith("[realms]")) { // Reconfig global setting - fw.write("max_retries = 2\n"); + fw.write("max_retries = 3\n"); fw.write("kdc_timeout = " + BadKdc.toReal(5000) + "\n"); } else if (s.trim().startsWith("kdc = ")) { if (value != -1) { From b37267c86640cbb222ba8830c55f05a9e4eeda14 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Wed, 17 Aug 2016 14:40:12 -0400 Subject: [PATCH 09/18] 8164071: Default.policy file missing content for solaris Reviewed-by: erikj --- jdk/make/copy/Copy-java.base.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/make/copy/Copy-java.base.gmk b/jdk/make/copy/Copy-java.base.gmk index 5fb26d4b4d2..c023e8cfbed 100644 --- a/jdk/make/copy/Copy-java.base.gmk +++ b/jdk/make/copy/Copy-java.base.gmk @@ -183,7 +183,7 @@ DEF_POLICY_DST := $(LIB_DST_DIR)/security/default.policy DEF_POLICY_SRC_LIST := $(DEF_POLICY_SRC) -ifeq ($(OPENJDK_TARGET_OS), windows) +ifneq ($(filter $(OPENJDK_TARGET_OS), windows solaris), ) DEF_POLICY_SRC_LIST += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/lib/security/default.policy endif From 5343687991fc80fc595f9b153ebd09bcd6d6e9f3 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Wed, 17 Aug 2016 21:14:39 +0100 Subject: [PATCH 10/18] 6977937: The SunJCE PBKDF2KeyImpl is requiring the MAC instance also be from SunJCE Reviewed-by: xuelei, ascarpino, wetmore --- .../share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java index 134a60096c2..87c3da39c8c 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,7 +107,7 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey { throw new InvalidKeySpecException("Key length is negative"); } try { - this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance()); + this.prf = Mac.getInstance(prfAlgo); } catch (NoSuchAlgorithmException nsae) { // not gonna happen; re-throw just in case InvalidKeySpecException ike = new InvalidKeySpecException(); From 697ec31ecf5dea2a97b115bc436935e779150615 Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Wed, 17 Aug 2016 16:03:52 -0700 Subject: [PATCH 11/18] 8156192: Provider#compute and #merge methods expect wrong permission & #compute ClassCastException even with wrong permission Reviewed-by: mullan, jnimeh --- .../share/classes/java/security/Provider.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/security/Provider.java b/jdk/src/java.base/share/classes/java/security/Provider.java index f9b0583df84..1d9d072b700 100644 --- a/jdk/src/java.base/share/classes/java/security/Provider.java +++ b/jdk/src/java.base/share/classes/java/security/Provider.java @@ -601,7 +601,7 @@ public abstract class Provider extends Properties { public synchronized Object compute(Object key, BiFunction remappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("Compute " + name + " provider property " + key); @@ -632,7 +632,7 @@ public abstract class Provider extends Properties { public synchronized Object computeIfAbsent(Object key, Function mappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("ComputeIfAbsent " + name + " provider property " + @@ -662,7 +662,7 @@ public abstract class Provider extends Properties { public synchronized Object computeIfPresent(Object key, BiFunction remappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("ComputeIfPresent " + name + " provider property " + @@ -695,7 +695,7 @@ public abstract class Provider extends Properties { public synchronized Object merge(Object key, Object value, BiFunction remappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("Merge " + name + " provider property " + key); @@ -904,8 +904,8 @@ public abstract class Provider extends Properties { if (!checkLegacy(key)) { return null; } - legacyStrings.computeIfAbsent((String) key, - (Function) remappingFunction); + legacyStrings.compute((String) key, + (BiFunction) remappingFunction); } return super.compute(key, remappingFunction); } From 004433bf70a814d9c8157328605eda7cf9b018b2 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Thu, 18 Aug 2016 12:39:23 -0400 Subject: [PATCH 12/18] 8161965: Create initial javadoc description for modules Reviewed-by: mchung, alanb, abuckley --- jdk/src/java.base/share/classes/module-info.java | 3 +-- jdk/src/java.compact1/share/classes/module-info.java | 3 +++ jdk/src/java.compact2/share/classes/module-info.java | 3 +++ jdk/src/java.compact3/share/classes/module-info.java | 4 ++++ jdk/src/java.datatransfer/share/classes/module-info.java | 4 +--- jdk/src/java.desktop/share/classes/module-info.java | 6 +++--- jdk/src/java.httpclient/share/classes/module-info.java | 3 +++ jdk/src/java.instrument/share/classes/module-info.java | 4 ++++ jdk/src/java.logging/share/classes/module-info.java | 3 +++ jdk/src/java.management/share/classes/module-info.java | 6 ++++++ jdk/src/java.naming/share/classes/module-info.java | 3 +++ jdk/src/java.prefs/share/classes/module-info.java | 3 +++ jdk/src/java.rmi/share/classes/module-info.java | 3 +++ jdk/src/java.scripting/share/classes/module-info.java | 3 +++ jdk/src/java.se.ee/share/classes/module-info.java | 6 ++++++ jdk/src/java.se/share/classes/module-info.java | 7 +++++++ jdk/src/java.security.jgss/share/classes/module-info.java | 5 +++++ jdk/src/java.security.sasl/share/classes/module-info.java | 7 +++++++ jdk/src/java.smartcardio/share/classes/module-info.java | 3 +++ jdk/src/java.sql.rowset/share/classes/module-info.java | 3 +++ jdk/src/java.sql/share/classes/module-info.java | 3 +++ jdk/src/java.transaction/share/classes/module-info.java | 6 ++++++ jdk/src/java.xml.crypto/share/classes/module-info.java | 3 +++ 23 files changed, 86 insertions(+), 8 deletions(-) diff --git a/jdk/src/java.base/share/classes/module-info.java b/jdk/src/java.base/share/classes/module-info.java index 044f43b2877..ae5ebbbb070 100644 --- a/jdk/src/java.base/share/classes/module-info.java +++ b/jdk/src/java.base/share/classes/module-info.java @@ -24,9 +24,8 @@ */ /** - * java.base defines and exports the core APIs of the Java SE platform. + * Defines the foundational APIs of the Java SE Platform. */ - module java.base { exports java.io; diff --git a/jdk/src/java.compact1/share/classes/module-info.java b/jdk/src/java.compact1/share/classes/module-info.java index 8c604682cd4..112c71b66e0 100644 --- a/jdk/src/java.compact1/share/classes/module-info.java +++ b/jdk/src/java.compact1/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Aggregates {@code java.base}, {@code java.logging}, and {@code java.scripting}. + */ module java.compact1 { requires public java.logging; requires public java.scripting; diff --git a/jdk/src/java.compact2/share/classes/module-info.java b/jdk/src/java.compact2/share/classes/module-info.java index 31a738dcd8b..b19902435d7 100644 --- a/jdk/src/java.compact2/share/classes/module-info.java +++ b/jdk/src/java.compact2/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Supplements {@code java.compact1} with JDBC, JAXP, and RMI. + */ module java.compact2 { requires public java.compact1; requires public java.rmi; diff --git a/jdk/src/java.compact3/share/classes/module-info.java b/jdk/src/java.compact3/share/classes/module-info.java index cbc67be6319..05f33c0da0e 100644 --- a/jdk/src/java.compact3/share/classes/module-info.java +++ b/jdk/src/java.compact3/share/classes/module-info.java @@ -23,6 +23,10 @@ * questions. */ +/** + * Supplements {@code java.compact2} with JDBC RowSet, JMX, JNDI, Compiler, + * Instrumentation, Preferences, Security, and XML cryptography APIs. + */ module java.compact3 { requires public java.compact2; requires public java.compiler; diff --git a/jdk/src/java.datatransfer/share/classes/module-info.java b/jdk/src/java.datatransfer/share/classes/module-info.java index 2a19571e3b4..ea3f9c2a53c 100644 --- a/jdk/src/java.datatransfer/share/classes/module-info.java +++ b/jdk/src/java.datatransfer/share/classes/module-info.java @@ -24,10 +24,8 @@ */ /** - * Provides interfaces and classes for transferring data between and - * within applications. + * Defines an API for transferring data between and within applications. */ - module java.datatransfer { exports java.awt.datatransfer; exports sun.datatransfer to java.desktop; diff --git a/jdk/src/java.desktop/share/classes/module-info.java b/jdk/src/java.desktop/share/classes/module-info.java index 504c0c25451..93ab9a46aa2 100644 --- a/jdk/src/java.desktop/share/classes/module-info.java +++ b/jdk/src/java.desktop/share/classes/module-info.java @@ -24,9 +24,9 @@ */ /** - * java.desktop defines and exports the user interface, graphics - * and imaging APIs of the Java SE platform. - */ + * Defines the AWT and Swing user interface toolkits, plus APIs for + * accessibility, audio, imaging, printing, and JavaBeans. + */ module java.desktop { requires public java.datatransfer; requires public java.xml; diff --git a/jdk/src/java.httpclient/share/classes/module-info.java b/jdk/src/java.httpclient/share/classes/module-info.java index 5adf7f6e5b2..f24416d1dfb 100644 --- a/jdk/src/java.httpclient/share/classes/module-info.java +++ b/jdk/src/java.httpclient/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the high-level HTTP and WebSocket API. + */ module java.httpclient { requires java.base; exports java.net.http; diff --git a/jdk/src/java.instrument/share/classes/module-info.java b/jdk/src/java.instrument/share/classes/module-info.java index 3eb704c6eab..27587d2c250 100644 --- a/jdk/src/java.instrument/share/classes/module-info.java +++ b/jdk/src/java.instrument/share/classes/module-info.java @@ -23,6 +23,10 @@ * questions. */ +/** + * Defines services that allow agents to + * instrument programs running on the JVM. + */ module java.instrument { exports java.lang.instrument; } diff --git a/jdk/src/java.logging/share/classes/module-info.java b/jdk/src/java.logging/share/classes/module-info.java index 47456e5ef5b..293d3873da1 100644 --- a/jdk/src/java.logging/share/classes/module-info.java +++ b/jdk/src/java.logging/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Java Logging API. + */ module java.logging { exports java.util.logging; provides jdk.internal.logger.DefaultLoggerFinder with diff --git a/jdk/src/java.management/share/classes/module-info.java b/jdk/src/java.management/share/classes/module-info.java index 8f7bd1b909e..6772da9d8ee 100644 --- a/jdk/src/java.management/share/classes/module-info.java +++ b/jdk/src/java.management/share/classes/module-info.java @@ -23,6 +23,12 @@ * questions. */ +/** + * Defines the Java Management Extensions (JMX) API. + *

+ * The JMX API consists of interfaces for monitoring and management of the + * JVM and other components in the Java runtime. + */ module java.management { requires public java.rmi; requires java.logging; diff --git a/jdk/src/java.naming/share/classes/module-info.java b/jdk/src/java.naming/share/classes/module-info.java index fb2e1018d76..b8964699610 100644 --- a/jdk/src/java.naming/share/classes/module-info.java +++ b/jdk/src/java.naming/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Java Naming and Directory Interface (JNDI) API. + */ module java.naming { requires java.security.sasl; diff --git a/jdk/src/java.prefs/share/classes/module-info.java b/jdk/src/java.prefs/share/classes/module-info.java index 3556b8eb395..4826cd2241b 100644 --- a/jdk/src/java.prefs/share/classes/module-info.java +++ b/jdk/src/java.prefs/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Preferences API. + */ module java.prefs { requires java.xml; diff --git a/jdk/src/java.rmi/share/classes/module-info.java b/jdk/src/java.rmi/share/classes/module-info.java index 44bd7288ca2..76195b6ec81 100644 --- a/jdk/src/java.rmi/share/classes/module-info.java +++ b/jdk/src/java.rmi/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Remote Method Invocation (RMI) API. + */ module java.rmi { requires java.logging; diff --git a/jdk/src/java.scripting/share/classes/module-info.java b/jdk/src/java.scripting/share/classes/module-info.java index b713ad0873b..b0a5baffc39 100644 --- a/jdk/src/java.scripting/share/classes/module-info.java +++ b/jdk/src/java.scripting/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Scripting API. + */ module java.scripting { exports javax.script; uses javax.script.ScriptEngineFactory; diff --git a/jdk/src/java.se.ee/share/classes/module-info.java b/jdk/src/java.se.ee/share/classes/module-info.java index 6d4a11fc70a..d611f5ef522 100644 --- a/jdk/src/java.se.ee/share/classes/module-info.java +++ b/jdk/src/java.se.ee/share/classes/module-info.java @@ -23,6 +23,12 @@ * questions. */ +/** + * Defines the full API of the Java SE Platform. + *

+ * This module requires {@code java.se} and supplements it with modules + * that define CORBA and Java EE APIs. These modules are upgradeable. + */ module java.se.ee { requires public java.se; diff --git a/jdk/src/java.se/share/classes/module-info.java b/jdk/src/java.se/share/classes/module-info.java index 73d5d05c093..26aeb030675 100644 --- a/jdk/src/java.se/share/classes/module-info.java +++ b/jdk/src/java.se/share/classes/module-info.java @@ -23,6 +23,13 @@ * questions. */ +/** + * Defines the core Java SE API. + *

+ * The modules defining + * CORBA and Java EE APIs are not required by this module, but they are + * required by {@code java.se.ee}. + */ module java.se { requires public java.compact3; requires public java.datatransfer; diff --git a/jdk/src/java.security.jgss/share/classes/module-info.java b/jdk/src/java.security.jgss/share/classes/module-info.java index 0a1e6c02f7c..6380721852c 100644 --- a/jdk/src/java.security.jgss/share/classes/module-info.java +++ b/jdk/src/java.security.jgss/share/classes/module-info.java @@ -23,6 +23,11 @@ * questions. */ +/** + * Defines the Java binding of the IETF Generic Security Services API (GSS-API). + *

+ * This module also contains GSS-API mechanisms including Kerberos v5 and SPNEGO. + */ module java.security.jgss { requires java.naming; exports javax.security.auth.kerberos; diff --git a/jdk/src/java.security.sasl/share/classes/module-info.java b/jdk/src/java.security.sasl/share/classes/module-info.java index ca06592ac70..70f860b3ce9 100644 --- a/jdk/src/java.security.sasl/share/classes/module-info.java +++ b/jdk/src/java.security.sasl/share/classes/module-info.java @@ -23,6 +23,13 @@ * questions. */ +/** + * Defines Java support for the IETF Simple Authentication and Security Layer + * (SASL). + *

+ * This module also contains SASL mechanisms including DIGEST-MD5, + * CRAM-MD5, and NTLM. + */ module java.security.sasl { requires java.logging; diff --git a/jdk/src/java.smartcardio/share/classes/module-info.java b/jdk/src/java.smartcardio/share/classes/module-info.java index 18f39988cc8..05f4588cbf6 100644 --- a/jdk/src/java.smartcardio/share/classes/module-info.java +++ b/jdk/src/java.smartcardio/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Java Smart Card I/O API. + */ module java.smartcardio { exports javax.smartcardio; provides java.security.Provider with sun.security.smartcardio.SunPCSC; diff --git a/jdk/src/java.sql.rowset/share/classes/module-info.java b/jdk/src/java.sql.rowset/share/classes/module-info.java index a1cd9ce5772..8d24418b6f2 100644 --- a/jdk/src/java.sql.rowset/share/classes/module-info.java +++ b/jdk/src/java.sql.rowset/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the JDBC RowSet API. + */ module java.sql.rowset { requires public java.logging; requires public java.naming; diff --git a/jdk/src/java.sql/share/classes/module-info.java b/jdk/src/java.sql/share/classes/module-info.java index 30683d94b06..70764a06d73 100644 --- a/jdk/src/java.sql/share/classes/module-info.java +++ b/jdk/src/java.sql/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the JDBC API. + */ module java.sql { requires public java.logging; requires public java.xml; diff --git a/jdk/src/java.transaction/share/classes/module-info.java b/jdk/src/java.transaction/share/classes/module-info.java index de572d90cb5..84daf74a27d 100644 --- a/jdk/src/java.transaction/share/classes/module-info.java +++ b/jdk/src/java.transaction/share/classes/module-info.java @@ -23,6 +23,12 @@ * questions. */ +/** + * Defines a subset of the Java Transaction API (JTA) to support CORBA interop. + *

+ * The subset consists of RMI exception types which are mapped to CORBA system + * exceptions by the 'Java Language to IDL Mapping Specification'. + */ module java.transaction { requires public java.rmi; exports javax.transaction; diff --git a/jdk/src/java.xml.crypto/share/classes/module-info.java b/jdk/src/java.xml.crypto/share/classes/module-info.java index 1c92d07ad80..62694bba195 100644 --- a/jdk/src/java.xml.crypto/share/classes/module-info.java +++ b/jdk/src/java.xml.crypto/share/classes/module-info.java @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines an API for XML cryptography. + */ module java.xml.crypto { requires public java.xml; requires java.logging; From ae448d6e828d2a07dc3406df698fc393257c472c Mon Sep 17 00:00:00 2001 From: Svetlana Nikandrova Date: Thu, 18 Aug 2016 16:27:15 +0300 Subject: [PATCH 13/18] 8146602: jdk/test/sun/misc/URLClassPath/ClassnameCharTest.java test fails with NullPointerException Reviewed-by: dfuchs, clanger --- .../misc/URLClassPath/ClassnameCharTest.java | 64 ++++++++++++++++--- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/jdk/test/sun/misc/URLClassPath/ClassnameCharTest.java b/jdk/test/sun/misc/URLClassPath/ClassnameCharTest.java index aba760aded1..ea873180b78 100644 --- a/jdk/test/sun/misc/URLClassPath/ClassnameCharTest.java +++ b/jdk/test/sun/misc/URLClassPath/ClassnameCharTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,16 +103,60 @@ public class ClassnameCharTest { //--------------------- Infrastructure --------------------------- static volatile int passed = 0, failed = 0; - static boolean pass() {passed++; return true;} - static boolean fail() {failed++; server.stop(0); Thread.dumpStack(); return false;} - static boolean fail(String msg) {System.out.println(msg); return fail();} - static void unexpected(Throwable t) {failed++; server.stop(0); t.printStackTrace();} - static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;} + + static boolean pass() { + passed++; + return true; + } + + static boolean fail() { + failed++; + if (server != null) { + server.stop(0); + } + Thread.dumpStack(); + return false; + } + + static boolean fail(String msg) { + System.out.println(msg); + return fail(); + } + + static void unexpected(Throwable t) { + failed++; + if (server != null) { + server.stop(0); + } + t.printStackTrace(); + } + + static boolean check(boolean cond) { + if (cond) { + pass(); + } else { + fail(); + } + return cond; + } + static boolean equal(Object x, Object y) { - if (x == null ? y == null : x.equals(y)) return pass(); - else return fail(x + " not equal to " + y);} + if (x == null ? y == null : x.equals(y)) { + return pass(); + } else { + return fail(x + " not equal to " + y); + } + } + public static void main(String[] args) throws Throwable { - try {realMain(args);} catch (Throwable t) {unexpected(t);} + try { + realMain(args); + } catch (Throwable t) { + unexpected(t); + } System.out.println("\nPassed = " + passed + " failed = " + failed); - if (failed > 0) throw new AssertionError("Some tests failed");} + if (failed > 0) { + throw new AssertionError("Some tests failed"); + } + } } From f657bd2fa96d1d51e1de48f69b44d929d5e87f49 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Thu, 18 Aug 2016 09:52:43 -0700 Subject: [PATCH 14/18] 8164329: Problem list sun/rmi/runtime/Log/6409194/NoConsoleOutput.java on windows due to JDK-8164124 Reviewed-by: darcy --- jdk/test/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 5bad9db84d4..50eb6e6b321 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -211,6 +211,8 @@ sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic- java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all +sun/rmi/runtime/Log/6409194/NoConsoleOutput.java 8164124 windows-all + ############################################################################ # jdk_security From 9dcafe04f0ad281ecbe50ccdb4f45ccb9a77e4e6 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Thu, 18 Aug 2016 19:00:39 +0200 Subject: [PATCH 15/18] 8164044: Generate corresponding simple DelegatingMethodHandles when generating a DirectMethodHandle at link time Reviewed-by: vlivanov, mhaupt, shade --- .../java/lang/invoke/BoundMethodHandle.java | 3 +- .../lang/invoke/DelegatingMethodHandle.java | 31 ++++++-- .../java/lang/invoke/DirectMethodHandle.java | 26 ++++--- .../lang/invoke/GenerateJLIClassesHelper.java | 76 ++++++++++++++++--- .../lang/invoke/InvokerBytecodeGenerator.java | 43 ++++++++++- .../classes/java/lang/invoke/LambdaForm.java | 72 +++++++++++------- .../java/lang/invoke/MethodHandleImpl.java | 15 +++- .../internal/misc/JavaLangInvokeAccess.java | 13 +++- .../plugins/GenerateJLIClassesPlugin.java | 47 +++++++++--- .../lang/StackWalker/VerifyStackTrace.java | 4 + 10 files changed, 254 insertions(+), 76 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java index 3b6fad7a636..91071a2b3b4 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java @@ -36,7 +36,6 @@ import sun.invoke.util.Wrapper; import java.lang.invoke.LambdaForm.NamedFunction; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.function.Function; @@ -308,7 +307,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*; /*non-public*/ char fieldTypeChar(int i) { return typeChars.charAt(i); } - Object fieldSignature() { + String fieldSignature() { return typeChars; } public Class fieldHolder() { diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java index 2e4baec0857..d11012e6487 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java @@ -27,6 +27,7 @@ package java.lang.invoke; import java.util.Arrays; import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleStatics.*; /** @@ -96,14 +97,8 @@ abstract class DelegatingMethodHandle extends MethodHandle { int whichCache, Object constraint, NamedFunction getTargetFn) { - String debugString; - switch(whichCache) { - case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; - case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; - default: debugString = "MH.reinvoke"; break; - } // No pre-action needed. - return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null); + return makeReinvokerForm(target, whichCache, constraint, null, true, getTargetFn, null); } /** Create a LF which simply reinvokes a target of the given basic type. */ static LambdaForm makeReinvokerForm(MethodHandle target, @@ -114,6 +109,10 @@ abstract class DelegatingMethodHandle extends MethodHandle { NamedFunction getTargetFn, NamedFunction preActionFn) { MethodType mtype = target.type().basicType(); + Kind kind = whichKind(whichCache); + if (debugString == null) { + debugString = kind.defaultLambdaName; + } boolean customized = (whichCache < 0 || mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); boolean hasPreAction = (preActionFn != null); @@ -145,13 +144,21 @@ abstract class DelegatingMethodHandle extends MethodHandle { targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs); } - form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline); + form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline, kind); if (!customized) { form = mtype.form().setCachedLambdaForm(whichCache, form); } return form; } + private static Kind whichKind(int whichCache) { + switch(whichCache) { + case MethodTypeForm.LF_REBIND: return BOUND_REINVOKER; + case MethodTypeForm.LF_DELEGATE: return DELEGATE; + default: return REINVOKER; + } + } + static final NamedFunction NF_getTarget; static { try { @@ -160,5 +167,13 @@ abstract class DelegatingMethodHandle extends MethodHandle { } catch (ReflectiveOperationException ex) { throw newInternalError(ex); } + // The Holder class will contain pre-generated DelegatingMethodHandles resolved + // speculatively using MemberName.getFactory().resolveOrNull. However, that + // doesn't initialize the class, which subtly breaks inlining etc. By forcing + // initialization of the Holder class we avoid these issues. + UNSAFE.ensureClassInitialized(Holder.class); } + + /* Placeholder class for DelegatingMethodHandles generated ahead of time */ + final class Holder {} } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java index 494103f57cc..174e914f805 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -38,6 +38,7 @@ import java.util.Arrays; import java.util.Objects; import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.UNSAFE; import static java.lang.invoke.MethodHandleStatics.newInternalError; @@ -189,14 +190,15 @@ class DirectMethodHandle extends MethodHandle { static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) { boolean needsInit = (which == LF_INVSTATIC_INIT); boolean doesAlloc = (which == LF_NEWINVSPECIAL); - String linkerName, lambdaName; + String linkerName; + LambdaForm.Kind kind; switch (which) { - case LF_INVVIRTUAL: linkerName = "linkToVirtual"; lambdaName = "DMH.invokeVirtual"; break; - case LF_INVSTATIC: linkerName = "linkToStatic"; lambdaName = "DMH.invokeStatic"; break; - case LF_INVSTATIC_INIT:linkerName = "linkToStatic"; lambdaName = "DMH.invokeStaticInit"; break; - case LF_INVSPECIAL: linkerName = "linkToSpecial"; lambdaName = "DMH.invokeSpecial"; break; - case LF_INVINTERFACE: linkerName = "linkToInterface"; lambdaName = "DMH.invokeInterface"; break; - case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; lambdaName = "DMH.newInvokeSpecial"; break; + case LF_INVVIRTUAL: linkerName = "linkToVirtual"; kind = DIRECT_INVOKE_VIRTUAL; break; + case LF_INVSTATIC: linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC; break; + case LF_INVSTATIC_INIT:linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC_INIT; break; + case LF_INVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_INVOKE_SPECIAL; break; + case LF_INVINTERFACE: linkerName = "linkToInterface"; kind = DIRECT_INVOKE_INTERFACE; break; + case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_NEW_INVOKE_SPECIAL; break; default: throw new InternalError("which="+which); } @@ -240,11 +242,11 @@ class DirectMethodHandle extends MethodHandle { result = NEW_OBJ; } names[LINKER_CALL] = new Name(linker, outArgs); - lambdaName += "_" + shortenSignature(basicTypeSignature(mtype)); - LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result); + String lambdaName = kind.defaultLambdaName + "_" + shortenSignature(basicTypeSignature(mtype)); + LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result, kind); // This is a tricky bit of code. Don't send it through the LF interpreter. - lform.compileToBytecode(Holder.class); + lform.compileToBytecode(); return lform; } @@ -705,7 +707,7 @@ class DirectMethodHandle extends MethodHandle { } static { - // The DMH class will contain pre-generated DirectMethodHandles resolved + // The Holder class will contain pre-generated DirectMethodHandles resolved // speculatively using MemberName.getFactory().resolveOrNull. However, that // doesn't initialize the class, which subtly breaks inlining etc. By forcing // initialization of the Holder class we avoid these issues. @@ -713,5 +715,5 @@ class DirectMethodHandle extends MethodHandle { } /* Placeholder class for DirectMethodHandles generated ahead of time */ - private final class Holder {} + final class Holder {} } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java b/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java index 5edf33c8c60..1f1b50d67c5 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java @@ -29,21 +29,56 @@ import java.util.Map; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Opcodes; +import java.util.ArrayList; +import java.util.HashSet; + /** * Helper class to assist the GenerateJLIClassesPlugin to get access to * generate classes ahead of time. */ class GenerateJLIClassesHelper { - static byte[] generateDMHClassBytes(String className, + static byte[] generateDirectMethodHandleHolderClassBytes(String className, MethodType[] methodTypes, int[] types) { LambdaForm[] forms = new LambdaForm[methodTypes.length]; + String[] names = new String[methodTypes.length]; for (int i = 0; i < forms.length; i++) { forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i], types[i]); - methodTypes[i] = forms[i].methodType(); + names[i] = forms[i].kind.defaultLambdaName; } - return generateCodeBytesForLFs(className, forms, methodTypes); + return generateCodeBytesForLFs(className, names, forms); + } + + static byte[] generateDelegatingMethodHandleHolderClassBytes(String className, + MethodType[] methodTypes) { + + HashSet dedupSet = new HashSet<>(); + ArrayList forms = new ArrayList<>(); + ArrayList names = new ArrayList<>(); + for (int i = 0; i < methodTypes.length; i++) { + // generate methods representing the DelegatingMethodHandle + if (dedupSet.add(methodTypes[i])) { + // reinvokers are variant with the associated SpeciesData + // and shape of the target LF, but we can easily pregenerate + // the basic reinvokers associated with Species_L. Ultimately we + // may want to consider pregenerating more of these, which will + // require an even more complex naming scheme + LambdaForm reinvoker = makeReinvokerFor(methodTypes[i]); + forms.add(reinvoker); + String speciesSig = BoundMethodHandle + .speciesData(reinvoker).fieldSignature(); + assert(speciesSig.equals("L")); + names.add(reinvoker.kind.defaultLambdaName + "_" + speciesSig); + + LambdaForm delegate = makeDelegateFor(methodTypes[i]); + forms.add(delegate); + names.add(delegate.kind.defaultLambdaName); + } + } + return generateCodeBytesForLFs(className, + names.toArray(new String[0]), + forms.toArray(new LambdaForm[0])); } /* @@ -51,22 +86,45 @@ class GenerateJLIClassesHelper { * a class with a specified name. */ private static byte[] generateCodeBytesForLFs(String className, - LambdaForm[] forms, MethodType[] types) { - assert(forms.length == types.length); + String[] names, LambdaForm[] forms) { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null); cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null); + for (int i = 0; i < forms.length; i++) { - InvokerBytecodeGenerator g - = new InvokerBytecodeGenerator(className, forms[i], types[i]); - g.setClassWriter(cw); - g.addMethod(); + addMethod(className, names[i], forms[i], + forms[i].methodType(), cw); } return cw.toByteArray(); } + private static void addMethod(String className, String methodName, LambdaForm form, + MethodType type, ClassWriter cw) { + InvokerBytecodeGenerator g + = new InvokerBytecodeGenerator(className, methodName, form, type); + g.setClassWriter(cw); + g.addMethod(); + } + + private static LambdaForm makeReinvokerFor(MethodType type) { + MethodHandle emptyHandle = MethodHandles.empty(type); + return DelegatingMethodHandle.makeReinvokerForm(emptyHandle, + MethodTypeForm.LF_REBIND, + BoundMethodHandle.speciesData_L(), + BoundMethodHandle.speciesData_L().getterFunction(0)); + } + + private static LambdaForm makeDelegateFor(MethodType type) { + MethodHandle handle = MethodHandles.empty(type); + return DelegatingMethodHandle.makeReinvokerForm( + handle, + MethodTypeForm.LF_DELEGATE, + DelegatingMethodHandle.class, + DelegatingMethodHandle.NF_getTarget); + } + static Map.Entry generateConcreteBMHClassBytes( final String types) { for (char c : types.toCharArray()) { diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 3508a11b049..ebfe415fbf1 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -46,6 +46,7 @@ import java.util.stream.Stream; import static java.lang.invoke.LambdaForm.*; import static java.lang.invoke.LambdaForm.BasicType.*; +import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.*; @@ -125,9 +126,15 @@ class InvokerBytecodeGenerator { } /** For generating customized code for a single LambdaForm. */ - InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { + private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { + this(className, form.debugName, form, invokerType); + } + + /** For generating customized code for a single LambdaForm. */ + InvokerBytecodeGenerator(String className, String invokerName, + LambdaForm form, MethodType invokerType) { this(form, form.names.length, - className, form.debugName, invokerType); + className, invokerName, invokerType); // Create an array to map name indexes to locals indexes. Name[] names = form.names; for (int i = 0, index = 0; i < localsMap.length; i++) { @@ -597,10 +604,42 @@ class InvokerBytecodeGenerator { return c.getName().replace('.', '/'); } + private static MemberName resolveFrom(String name, MethodType type, Class holder) { + MemberName member = new MemberName(holder, name, type, REF_invokeStatic); + MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder); + + return resolvedMember; + } + + private static MemberName lookupPregenerated(LambdaForm form) { + if (form.customized != null) { + // No pre-generated version for customized LF + return null; + } + MethodType invokerType = form.methodType(); + String name = form.kind.methodName; + switch (form.kind) { + case BOUND_REINVOKER: { + name = name + "_" + BoundMethodHandle.speciesData(form).fieldSignature(); + return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); + } + case DELEGATE: return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); + case DIRECT_INVOKE_INTERFACE: // fall-through + case DIRECT_INVOKE_SPECIAL: // fall-through + case DIRECT_INVOKE_STATIC: // fall-through + case DIRECT_INVOKE_STATIC_INIT: // fall-through + case DIRECT_INVOKE_VIRTUAL: return resolveFrom(name, invokerType, DirectMethodHandle.Holder.class); + } + return null; + } + /** * Generate customized bytecode for a given LambdaForm. */ static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) { + MemberName pregenerated = lookupPregenerated(form); + if (pregenerated != null) return pregenerated; // pre-generated bytecode + InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType); return g.loadMethod(g.generateCustomizedCodeBytes()); } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java index a007881252f..c70d6c4163a 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java @@ -41,6 +41,7 @@ import java.util.HashMap; import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic; import static java.lang.invoke.MethodHandleStatics.*; +import java.util.Objects; /** * The symbolic, non-executable form of a method handle's invocation semantics. @@ -127,6 +128,7 @@ class LambdaForm { final MethodHandle customized; @Stable final Name[] names; final String debugName; + final Kind kind; MemberName vmentry; // low-level behavior, or null if not yet prepared private boolean isCompiled; @@ -266,12 +268,46 @@ class LambdaForm { } } + enum Kind { + GENERIC(""), + BOUND_REINVOKER("BMH.reinvoke"), + REINVOKER("MH.reinvoke"), + DELEGATE("MH.delegate"), + DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"), + DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"), + DIRECT_INVOKE_STATIC("DMH.invokeStatic"), + DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"), + DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"), + DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"); + + final String defaultLambdaName; + final String methodName; + + private Kind(String defaultLambdaName) { + this.defaultLambdaName = defaultLambdaName; + int p = defaultLambdaName.indexOf('.'); + if (p > -1) { + this.methodName = defaultLambdaName.substring(p + 1); + } else { + this.methodName = defaultLambdaName; + } + } + } + LambdaForm(String debugName, int arity, Name[] names, int result) { - this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null); + this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, int result, Kind kind) { + this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, kind); } LambdaForm(String debugName, int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) { + this(debugName, arity, names, result, forceInline, customized, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, int result, boolean forceInline, MethodHandle customized, Kind kind) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); @@ -279,6 +315,7 @@ class LambdaForm { this.debugName = fixDebugName(debugName); this.forceInline = forceInline; this.customized = customized; + this.kind = kind; int maxOutArity = normalize(); if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) { // Cannot use LF interpreter on very high arity expressions. @@ -288,11 +325,15 @@ class LambdaForm { } LambdaForm(String debugName, int arity, Name[] names) { - this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null); + this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); } LambdaForm(String debugName, int arity, Name[] names, boolean forceInline) { - this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null); + this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, boolean forceInline, Kind kind) { + this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, kind); } LambdaForm(String debugName, Name[] formals, Name[] temps, Name result) { @@ -325,6 +366,7 @@ class LambdaForm { this.debugName = "LF.zero"; this.forceInline = true; this.customized = null; + this.kind = Kind.GENERIC; assert(nameRefsAreLegal()); assert(isEmpty()); String sig = null; @@ -395,7 +437,7 @@ class LambdaForm { /** Customize LambdaForm for a particular MethodHandle */ LambdaForm customize(MethodHandle mh) { - LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh); + LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh, kind); if (COMPILE_THRESHOLD >= 0 && isCompiled) { // If shared LambdaForm has been compiled, compile customized version as well. customForm.compileToBytecode(); @@ -773,28 +815,6 @@ class LambdaForm { } } - /** - * Generate optimizable bytecode for this form after first looking for a - * pregenerated version in a specified class. - */ - void compileToBytecode(Class lookupClass) { - if (vmentry != null && isCompiled) { - return; // already compiled somehow - } - MethodType invokerType = methodType(); - assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType)); - int dot = debugName.indexOf('.'); - String methodName = (dot > 0) ? debugName.substring(dot + 1) : debugName; - MemberName member = new MemberName(lookupClass, methodName, invokerType, REF_invokeStatic); - MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, lookupClass); - if (resolvedMember != null) { - vmentry = resolvedMember; - isCompiled = true; - } else { - compileToBytecode(); - } - } - private static void computeInitialPreparedForms() { // Find all predefined invokers and associate them with canonical empty lambda forms. for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) { diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index 60dc84f65ed..a0561589beb 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -1718,10 +1718,19 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*; } @Override - public byte[] generateDMHClassBytes(String className, - MethodType[] methodTypes, int[] types) { + public byte[] generateDirectMethodHandleHolderClassBytes( + String className, MethodType[] methodTypes, int[] types) { return GenerateJLIClassesHelper - .generateDMHClassBytes(className, methodTypes, types); + .generateDirectMethodHandleHolderClassBytes( + className, methodTypes, types); + } + + @Override + public byte[] generateDelegatingMethodHandleHolderClassBytes( + String className, MethodType[] methodTypes) { + return GenerateJLIClassesHelper + .generateDelegatingMethodHandleHolderClassBytes( + className, methodTypes); } @Override diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java index e514e5c95c0..ea941316b4e 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java @@ -51,8 +51,17 @@ public interface JavaLangInvokeAccess { * an {@code int} representing method type. Used by * GenerateJLIClassesPlugin to generate such a class during the jlink phase. */ - byte[] generateDMHClassBytes(String className, MethodType[] methodTypes, - int[] types); + byte[] generateDirectMethodHandleHolderClassBytes(String className, + MethodType[] methodTypes, int[] types); + + /** + * Returns a {@code byte[]} containing the bytecode for a class implementing + * DelegatingMethodHandles of each {@code MethodType} kind in the + * {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to + * generate such a class during the jlink phase. + */ + byte[] generateDelegatingMethodHandleHolderClassBytes(String className, + MethodType[] methodTypes); /** * Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java index 1697e988b53..3866c95c2dc 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java @@ -55,7 +55,7 @@ public final class GenerateJLIClassesPlugin implements Plugin { private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME); - private static final String DMH = "java/lang/invoke/DirectMethodHandle$Holder"; + private static final String DIRECT_METHOD_HANDLE = "java/lang/invoke/DirectMethodHandle$Holder"; private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual"; private static final String DMH_INVOKE_STATIC = "invokeStatic"; private static final String DMH_INVOKE_SPECIAL = "invokeSpecial"; @@ -63,6 +63,8 @@ public final class GenerateJLIClassesPlugin implements Plugin { private static final String DMH_INVOKE_INTERFACE = "invokeInterface"; private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit"; + private static final String DELEGATING_METHOD_HANDLE = "java/lang/invoke/DelegatingMethodHandle$Holder"; + private static final JavaLangInvokeAccess JLIA = SharedSecrets.getJavaLangInvokeAccess(); @@ -222,7 +224,15 @@ public final class GenerateJLIClassesPlugin implements Plugin { @Override public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) { // Copy all but DMH_ENTRY to out - in.transformAndCopy(entry -> entry.path().equals(DMH_ENTRY) ? null : entry, out); + in.transformAndCopy(entry -> { + // filter out placeholder entries + if (entry.path().equals(DIRECT_METHOD_HANDLE_ENTRY) || + entry.path().equals(DELEGATING_METHOD_HANDLE_ENTRY)) { + return null; + } else { + return entry; + } + }, out); speciesTypes.forEach(types -> generateBMHClass(types, out)); generateDMHClass(out); return out.build(); @@ -264,15 +274,24 @@ public final class GenerateJLIClassesPlugin implements Plugin { } } try { - byte[] bytes = - JLIA.generateDMHClassBytes(DMH, methodTypes, dmhTypes); - ResourcePoolEntry ndata = ResourcePoolEntry.create(DMH_ENTRY, bytes); + byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes( + DIRECT_METHOD_HANDLE, methodTypes, dmhTypes); + ResourcePoolEntry ndata = ResourcePoolEntry + .create(DIRECT_METHOD_HANDLE_ENTRY, bytes); + out.add(ndata); + + bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes( + DELEGATING_METHOD_HANDLE, methodTypes); + ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HANDLE_ENTRY, bytes); out.add(ndata); } catch (Exception ex) { throw new PluginException(ex); } } - private static final String DMH_ENTRY = "/java.base/" + DMH + ".class"; + private static final String DIRECT_METHOD_HANDLE_ENTRY = + "/java.base/" + DIRECT_METHOD_HANDLE + ".class"; + private static final String DELEGATING_METHOD_HANDLE_ENTRY = + "/java.base/" + DELEGATING_METHOD_HANDLE + ".class"; // Convert LL -> LL, L3 -> LLL private static String expandSignature(String signature) { @@ -310,15 +329,19 @@ public final class GenerateJLIClassesPlugin implements Plugin { assert(parts.length == 2); assert(parts[1].length() == 1); String parameters = expandSignature(parts[0]); - Class rtype = primitiveType(parts[1].charAt(0)); - Class[] ptypes = new Class[parameters.length()]; - for (int i = 0; i < ptypes.length; i++) { - ptypes[i] = primitiveType(parameters.charAt(i)); + Class rtype = simpleType(parts[1].charAt(0)); + if (parameters.isEmpty()) { + return MethodType.methodType(rtype); + } else { + Class[] ptypes = new Class[parameters.length()]; + for (int i = 0; i < ptypes.length; i++) { + ptypes[i] = simpleType(parameters.charAt(i)); + } + return MethodType.methodType(rtype, ptypes); } - return MethodType.methodType(rtype, ptypes); } - private static Class primitiveType(char c) { + private static Class simpleType(char c) { switch (c) { case 'F': return float.class; diff --git a/jdk/test/java/lang/StackWalker/VerifyStackTrace.java b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java index eb4a5085a5a..2c70a6d02dc 100644 --- a/jdk/test/java/lang/StackWalker/VerifyStackTrace.java +++ b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java @@ -205,8 +205,12 @@ public class VerifyStackTrace { .replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/") .replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run") .replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke") + // DMHs may or may not be pre-generated, making frames differ .replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH") .replaceAll("DMH\\.invoke", "DMH/xxxxxxxx.invoke") + // invoke frames may or may not have basic method type + // information encoded for diagnostic purposes + .replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z]+_[A-Z]", "xx.invoke$1") .replaceAll("\\$[0-9]+", "\\$??"); } else { return produced; From 7cb94a8bf88cbbedac5fbfa85702140f61493dca Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Thu, 18 Aug 2016 15:05:02 -0400 Subject: [PATCH 16/18] 8138661: Minor correction in Java API doc for DataSource Reviewed-by: naoto --- jdk/src/java.sql/share/classes/javax/sql/DataSource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java index dbdfd4c07de..4c3274d22d9 100644 --- a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java +++ b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java @@ -64,7 +64,7 @@ import java.sql.Wrapper; *

* A driver that is accessed via a {@code DataSource} object does not * register itself with the {@code DriverManager}. Rather, a - * {@code DataSource} object is retrieved though a lookup operation + * {@code DataSource} object is retrieved through a lookup operation * and then used to create a {@code Connection} object. With a basic * implementation, the connection obtained through a {@code DataSource} * object is identical to a connection obtained through the From 25ff06c014932890fe88a3517632e16ebfdee8d7 Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Thu, 18 Aug 2016 22:07:09 +0300 Subject: [PATCH 17/18] 8163517: Various cleanup in java.io code Reviewed-by: shade, rriggs, redestad --- .../share/classes/java/io/BufferedReader.java | 2 +- .../java/io/ByteArrayOutputStream.java | 2 +- .../classes/java/io/CharArrayWriter.java | 13 +++++------ .../share/classes/java/io/FileSystem.java | 9 ++------ .../classes/java/io/ObjectInputStream.java | 16 ++++++-------- .../classes/java/io/ObjectOutputStream.java | 16 ++++++-------- .../classes/java/io/ObjectStreamClass.java | 20 ++++++++--------- .../classes/java/io/OutputStreamWriter.java | 14 ++++-------- .../share/classes/java/io/PrintStream.java | 17 +++++--------- .../share/classes/java/io/PrintWriter.java | 17 +++++--------- .../classes/java/io/SequenceInputStream.java | 22 ++++++------------- .../java/io/StringBufferInputStream.java | 9 +++----- .../share/classes/java/io/StringReader.java | 4 ++-- .../share/classes/java/io/StringWriter.java | 14 +++++------- .../share/classes/java/io/Writer.java | 14 +++++------- 15 files changed, 69 insertions(+), 120 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/io/BufferedReader.java b/jdk/src/java.base/share/classes/java/io/BufferedReader.java index 3940b3b8776..1f6a66490cd 100644 --- a/jdk/src/java.base/share/classes/java/io/BufferedReader.java +++ b/jdk/src/java.base/share/classes/java/io/BufferedReader.java @@ -560,7 +560,7 @@ public class BufferedReader extends Reader { * @since 1.8 */ public Stream lines() { - Iterator iter = new Iterator() { + Iterator iter = new Iterator<>() { String nextLine = null; @Override diff --git a/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java b/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java index 61a147d1c4d..bd867c08d76 100644 --- a/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java +++ b/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java @@ -187,7 +187,7 @@ public class ByteArrayOutputStream extends OutputStream { * @return the current contents of this output stream, as a byte array. * @see java.io.ByteArrayOutputStream#size() */ - public synchronized byte toByteArray()[] { + public synchronized byte[] toByteArray() { return Arrays.copyOf(buf, count); } diff --git a/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java b/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java index 773b59614d9..e8bf2c36167 100644 --- a/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java +++ b/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java @@ -165,7 +165,7 @@ class CharArrayWriter extends Writer { * * @param csq * The character sequence to append. If {@code csq} is - * {@code null}, then the four characters "{@code null}" are + * {@code null}, then the four characters {@code "null"} are * appended to this writer. * * @return This writer @@ -173,7 +173,7 @@ class CharArrayWriter extends Writer { * @since 1.5 */ public CharArrayWriter append(CharSequence csq) { - String s = (csq == null ? "null" : csq.toString()); + String s = String.valueOf(csq); write(s, 0, s.length()); return this; } @@ -193,7 +193,7 @@ class CharArrayWriter extends Writer { * The character sequence from which a subsequence will be * appended. If {@code csq} is {@code null}, then characters * will be appended as if {@code csq} contained the four - * characters "{@code null}". + * characters {@code "null"}. * * @param start * The index of the first character in the subsequence @@ -212,9 +212,8 @@ class CharArrayWriter extends Writer { * @since 1.5 */ public CharArrayWriter append(CharSequence csq, int start, int end) { - String s = (csq == null ? "null" : csq).subSequence(start, end).toString(); - write(s, 0, s.length()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /** @@ -251,7 +250,7 @@ class CharArrayWriter extends Writer { * * @return an array of chars copied from the input data. */ - public char toCharArray()[] { + public char[] toCharArray() { synchronized (lock) { return Arrays.copyOf(buf, count); } diff --git a/jdk/src/java.base/share/classes/java/io/FileSystem.java b/jdk/src/java.base/share/classes/java/io/FileSystem.java index 9d73e79ed40..a7528a9b5ca 100644 --- a/jdk/src/java.base/share/classes/java/io/FileSystem.java +++ b/jdk/src/java.base/share/classes/java/io/FileSystem.java @@ -228,13 +228,8 @@ abstract class FileSystem { static boolean useCanonPrefixCache = true; private static boolean getBooleanProperty(String prop, boolean defaultVal) { - String val = System.getProperty(prop); - if (val == null) return defaultVal; - if (val.equalsIgnoreCase("true")) { - return true; - } else { - return false; - } + return Boolean.parseBoolean(System.getProperty(prop, + String.valueOf(defaultVal))); } static { diff --git a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java index 9f13c9216a3..1895203cd11 100644 --- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -1265,22 +1265,21 @@ public class ObjectInputStream WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); Boolean result = Caches.subclassAudits.get(key); if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); + result = auditSubclass(cl); Caches.subclassAudits.putIfAbsent(key, result); } - if (result.booleanValue()) { - return; + if (!result) { + sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } /** * Performs reflective checks on given subclass to verify that it doesn't - * override security-sensitive non-final methods. Returns true if subclass - * is "safe", false otherwise. + * override security-sensitive non-final methods. Returns TRUE if subclass + * is "safe", FALSE otherwise. */ - private static boolean auditSubclass(final Class subcl) { - Boolean result = AccessController.doPrivileged( + private static Boolean auditSubclass(Class subcl) { + return AccessController.doPrivileged( new PrivilegedAction<>() { public Boolean run() { for (Class cl = subcl; @@ -1303,7 +1302,6 @@ public class ObjectInputStream } } ); - return result.booleanValue(); } /** diff --git a/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java b/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java index 2fc905e2dd3..bff6f8311ee 100644 --- a/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java +++ b/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java @@ -1050,22 +1050,21 @@ public class ObjectOutputStream WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); Boolean result = Caches.subclassAudits.get(key); if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); + result = auditSubclass(cl); Caches.subclassAudits.putIfAbsent(key, result); } - if (result.booleanValue()) { - return; + if (!result) { + sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } /** * Performs reflective checks on given subclass to verify that it doesn't - * override security-sensitive non-final methods. Returns true if subclass - * is "safe", false otherwise. + * override security-sensitive non-final methods. Returns TRUE if subclass + * is "safe", FALSE otherwise. */ - private static boolean auditSubclass(final Class subcl) { - Boolean result = AccessController.doPrivileged( + private static Boolean auditSubclass(Class subcl) { + return AccessController.doPrivileged( new PrivilegedAction<>() { public Boolean run() { for (Class cl = subcl; @@ -1088,7 +1087,6 @@ public class ObjectOutputStream } } ); - return result.booleanValue(); } /** diff --git a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java index cca42a71bbf..7ae45cae8c4 100644 --- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java +++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java @@ -1509,11 +1509,9 @@ public class ObjectStreamClass implements Serializable { private static String getPackageName(Class cl) { String s = cl.getName(); int i = s.lastIndexOf('['); - if (i >= 0) { - s = s.substring(i + 2); - } - i = s.lastIndexOf('.'); - return (i >= 0) ? s.substring(0, i) : ""; + i = (i < 0) ? 0 : i + 2; + int j = s.lastIndexOf('.'); + return (i < j) ? s.substring(i, j) : ""; } /** @@ -1535,14 +1533,14 @@ public class ObjectStreamClass implements Serializable { private static String getMethodSignature(Class[] paramTypes, Class retType) { - StringBuilder sbuf = new StringBuilder(); - sbuf.append('('); + StringBuilder sb = new StringBuilder(); + sb.append('('); for (int i = 0; i < paramTypes.length; i++) { - appendClassSignature(sbuf, paramTypes[i]); + appendClassSignature(sb, paramTypes[i]); } - sbuf.append(')'); - appendClassSignature(sbuf, retType); - return sbuf.toString(); + sb.append(')'); + appendClassSignature(sb, retType); + return sb.toString(); } /** diff --git a/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java b/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java index 4fdb148baaf..3d44f443b82 100644 --- a/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java +++ b/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java @@ -233,22 +233,16 @@ public class OutputStreamWriter extends Writer { @Override public Writer append(CharSequence csq, int start, int end) throws IOException { - if (csq == null) { - write("null".subSequence(start, end).toString()); - return this; - } else { - return append(csq.subSequence(start, end)); - } + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } @Override public Writer append(CharSequence csq) throws IOException { - if (csq == null) { - se.write("null"); - } else if (csq instanceof CharBuffer) { + if (csq instanceof CharBuffer) { se.write((CharBuffer) csq); } else { - se.write(csq.toString()); + se.write(String.valueOf(csq)); } return this; } diff --git a/jdk/src/java.base/share/classes/java/io/PrintStream.java b/jdk/src/java.base/share/classes/java/io/PrintStream.java index 36a271e804d..09028de7358 100644 --- a/jdk/src/java.base/share/classes/java/io/PrintStream.java +++ b/jdk/src/java.base/share/classes/java/io/PrintStream.java @@ -568,7 +568,7 @@ public class PrintStream extends FilterOutputStream * @param b The {@code boolean} to be printed */ public void print(boolean b) { - write(b ? "true" : "false"); + write(String.valueOf(b)); } /** @@ -663,10 +663,7 @@ public class PrintStream extends FilterOutputStream * @param s The {@code String} to be printed */ public void print(String s) { - if (s == null) { - s = "null"; - } - write(s); + write(String.valueOf(s)); } /** @@ -1068,10 +1065,7 @@ public class PrintStream extends FilterOutputStream * @since 1.5 */ public PrintStream append(CharSequence csq) { - if (csq == null) - print("null"); - else - print(csq.toString()); + print(String.valueOf(csq)); return this; } @@ -1111,9 +1105,8 @@ public class PrintStream extends FilterOutputStream * @since 1.5 */ public PrintStream append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /** diff --git a/jdk/src/java.base/share/classes/java/io/PrintWriter.java b/jdk/src/java.base/share/classes/java/io/PrintWriter.java index d516b8ef404..0513312781b 100644 --- a/jdk/src/java.base/share/classes/java/io/PrintWriter.java +++ b/jdk/src/java.base/share/classes/java/io/PrintWriter.java @@ -504,7 +504,7 @@ public class PrintWriter extends Writer { * @param b The {@code boolean} to be printed */ public void print(boolean b) { - write(b ? "true" : "false"); + write(String.valueOf(b)); } /** @@ -599,10 +599,7 @@ public class PrintWriter extends Writer { * @param s The {@code String} to be printed */ public void print(String s) { - if (s == null) { - s = "null"; - } - write(s); + write(String.valueOf(s)); } /** @@ -1005,10 +1002,7 @@ public class PrintWriter extends Writer { * @since 1.5 */ public PrintWriter append(CharSequence csq) { - if (csq == null) - write("null"); - else - write(csq.toString()); + write(String.valueOf(csq)); return this; } @@ -1047,9 +1041,8 @@ public class PrintWriter extends Writer { * @since 1.5 */ public PrintWriter append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /** diff --git a/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java b/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java index f68f7d25265..b2caa11bca9 100644 --- a/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java +++ b/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java @@ -65,12 +65,7 @@ class SequenceInputStream extends InputStream { */ public SequenceInputStream(Enumeration e) { this.e = e; - try { - nextStream(); - } catch (IOException ex) { - // This should never happen - throw new Error("panic"); - } + peekNextStream(); } /** @@ -86,16 +81,10 @@ class SequenceInputStream extends InputStream { */ public SequenceInputStream(InputStream s1, InputStream s2) { Vector v = new Vector<>(2); - v.addElement(s1); v.addElement(s2); e = v.elements(); - try { - nextStream(); - } catch (IOException ex) { - // This should never happen - throw new Error("panic"); - } + peekNextStream(); } /** @@ -105,14 +94,17 @@ class SequenceInputStream extends InputStream { if (in != null) { in.close(); } + peekNextStream(); + } + private void peekNextStream() { if (e.hasMoreElements()) { in = (InputStream) e.nextElement(); if (in == null) throw new NullPointerException(); + } else { + in = null; } - else in = null; - } /** diff --git a/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java b/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java index 787cbb9c45e..11c230ff932 100644 --- a/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java +++ b/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java @@ -108,6 +108,7 @@ class StringBufferInputStream extends InputStream { * -1 if there is no more data because the end of * the stream has been reached. */ + @SuppressWarnings("deprecation") public synchronized int read(byte b[], int off, int len) { if (b == null) { throw new NullPointerException(); @@ -126,12 +127,8 @@ class StringBufferInputStream extends InputStream { if (len <= 0) { return 0; } - String s = buffer; - int cnt = len; - while (--cnt >= 0) { - b[off++] = (byte)s.charAt(pos++); - } - + buffer.getBytes(pos, pos + len, b, off); + pos += len; return len; } diff --git a/jdk/src/java.base/share/classes/java/io/StringReader.java b/jdk/src/java.base/share/classes/java/io/StringReader.java index 2dd72ff5357..9cfe5412993 100644 --- a/jdk/src/java.base/share/classes/java/io/StringReader.java +++ b/jdk/src/java.base/share/classes/java/io/StringReader.java @@ -142,8 +142,8 @@ public class StringReader extends Reader { */ public boolean ready() throws IOException { synchronized (lock) { - ensureOpen(); - return true; + ensureOpen(); + return true; } } diff --git a/jdk/src/java.base/share/classes/java/io/StringWriter.java b/jdk/src/java.base/share/classes/java/io/StringWriter.java index 15022b353a8..16eed62d7bb 100644 --- a/jdk/src/java.base/share/classes/java/io/StringWriter.java +++ b/jdk/src/java.base/share/classes/java/io/StringWriter.java @@ -139,7 +139,7 @@ public class StringWriter extends Writer { * * @param csq * The character sequence to append. If {@code csq} is - * {@code null}, then the four characters "{@code null}" are + * {@code null}, then the four characters {@code "null"} are * appended to this writer. * * @return This writer @@ -147,10 +147,7 @@ public class StringWriter extends Writer { * @since 1.5 */ public StringWriter append(CharSequence csq) { - if (csq == null) - write("null"); - else - write(csq.toString()); + write(String.valueOf(csq)); return this; } @@ -170,7 +167,7 @@ public class StringWriter extends Writer { * The character sequence from which a subsequence will be * appended. If {@code csq} is {@code null}, then characters * will be appended as if {@code csq} contained the four - * characters "{@code null}". + * characters {@code "null"}. * * @param start * The index of the first character in the subsequence @@ -189,9 +186,8 @@ public class StringWriter extends Writer { * @since 1.5 */ public StringWriter append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /** diff --git a/jdk/src/java.base/share/classes/java/io/Writer.java b/jdk/src/java.base/share/classes/java/io/Writer.java index 17e8de3ef8a..cd9aded358f 100644 --- a/jdk/src/java.base/share/classes/java/io/Writer.java +++ b/jdk/src/java.base/share/classes/java/io/Writer.java @@ -221,7 +221,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable { * * @param csq * The character sequence to append. If {@code csq} is - * {@code null}, then the four characters "{@code null}" are + * {@code null}, then the four characters {@code "null"} are * appended to this writer. * * @return This writer @@ -232,10 +232,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable { * @since 1.5 */ public Writer append(CharSequence csq) throws IOException { - if (csq == null) - write("null"); - else - write(csq.toString()); + write(String.valueOf(csq)); return this; } @@ -256,7 +253,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable { * The character sequence from which a subsequence will be * appended. If {@code csq} is {@code null}, then characters * will be appended as if {@code csq} contained the four - * characters "{@code null}". + * characters {@code "null"}. * * @param start * The index of the first character in the subsequence @@ -278,9 +275,8 @@ public abstract class Writer implements Appendable, Closeable, Flushable { * @since 1.5 */ public Writer append(CharSequence csq, int start, int end) throws IOException { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /** From 632849163493ea4a7e06962353e98a1bd4f868b1 Mon Sep 17 00:00:00 2001 From: Jamil Nimeh Date: Thu, 18 Aug 2016 12:48:23 -0700 Subject: [PATCH 18/18] 8162808: Add references to the standard JSSE cipher suite names in javadoc Add hyperlinks to the cipher suite section of the Standard Names documentation for various SSL class methods when they reference cipher suites by name Reviewed-by: xuelei, mullan --- .../classes/javax/net/ssl/SSLEngine.java | 22 ++++++++++++++ .../classes/javax/net/ssl/SSLParameters.java | 30 +++++++++++++++++-- .../javax/net/ssl/SSLServerSocket.java | 22 ++++++++++++++ .../javax/net/ssl/SSLServerSocketFactory.java | 16 +++++++++- .../classes/javax/net/ssl/SSLSocket.java | 22 ++++++++++++++ .../javax/net/ssl/SSLSocketFactory.java | 16 +++++++++- 6 files changed, 123 insertions(+), 5 deletions(-) diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java index 3b222cf6ad7..300265cbcd4 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java @@ -861,6 +861,13 @@ public abstract class SSLEngine { * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites might be useful in specialized applications. + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -880,6 +887,13 @@ public abstract class SSLEngine { * or the requisite certificates (and private keys) for the suite are * not available, or an anonymous suite is enabled but authentication * is required. + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -896,6 +910,14 @@ public abstract class SSLEngine { * fail. Following a successful call to this method, only suites * listed in the {@code suites} parameter are enabled for use. *

+ * Note that the standard list of cipher suite names may be found in the + * + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. + *

* See {@link #getEnabledCipherSuites()} for more information * on why a specific cipher suite may never be used on a engine. * diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java index 5d47d37b909..5207c3c1f84 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,7 +108,12 @@ public class SSLParameters { *

* Calling this constructor is equivalent to calling the no-args * constructor followed by - * {@code setCipherSuites(cipherSuites);}. + * {@code setCipherSuites(cipherSuites);}. Note that the + * standard list of cipher suite names may be found in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) */ @@ -123,6 +128,12 @@ public class SSLParameters { * Calling this constructor is equivalent to calling the no-args * constructor followed by * {@code setCipherSuites(cipherSuites); setProtocols(protocols);}. + * Note that the standard list of cipher suite names may be found in the + * + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) * @param protocols the array of protocols (or null) @@ -139,6 +150,13 @@ public class SSLParameters { /** * Returns a copy of the array of ciphersuites or null if none * have been set. + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return a copy of the array of ciphersuites or null if none * have been set. @@ -150,7 +168,13 @@ public class SSLParameters { /** * Sets the array of ciphersuites. * - * @param cipherSuites the array of ciphersuites (or null) + * @param cipherSuites the array of ciphersuites (or null). Note that the + * standard list of cipher suite names may be found in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. */ public void setCipherSuites(String[] cipherSuites) { this.cipherSuites = clone(cipherSuites); diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java index 8c7d9dc3031..ead7d20ae58 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java @@ -195,6 +195,13 @@ public abstract class SSLServerSocket extends ServerSocket { * or the requisite certificates (and private keys) for the suite are * not available, or an anonymous suite is enabled but authentication * is required. + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suites enabled * @see #getSupportedCipherSuites() @@ -215,6 +222,14 @@ public abstract class SSLServerSocket extends ServerSocket { * in this ServerSocket's authentication context will not be used * in any case, even if they are enabled. *

+ * Note that the standard list of cipher suite names may be found in the + * + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. + *

* SSLSockets returned from accept() * inherit this setting. * @@ -236,6 +251,13 @@ public abstract class SSLServerSocket extends ServerSocket { * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites are useful in specialized applications. + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java index fea47ba0cd3..3629aaef3c7 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -123,6 +123,13 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory * will use one of these cipher suites. The minimum quality of service * for these defaults requires confidentiality protection and server * authentication (that is, no anonymous cipher suites). + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -137,6 +144,13 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites are useful in specialized applications. + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getDefaultCipherSuites() diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java index 93c7ec01ab7..daaefe08ec7 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java @@ -265,6 +265,13 @@ public abstract class SSLSocket extends Socket * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites might be useful in specialized applications. + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -284,6 +291,13 @@ public abstract class SSLSocket extends Socket * or the requisite certificates (and private keys) for the suite are * not available, or an anonymous suite is enabled but authentication * is required. + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -300,6 +314,14 @@ public abstract class SSLSocket extends Socket * fail. Following a successful call to this method, only suites * listed in the suites parameter are enabled for use. *

+ * Note that the standard list of cipher suite names may be found in the + * + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. + *

* See {@link #getEnabledCipherSuites()} for more information * on why a specific ciphersuite may never be used on a connection. * diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java index 6375a52a1b0..d504e1d7a3d 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,6 +148,13 @@ public abstract class SSLSocketFactory extends SocketFactory * will use one of these cipher suites. The minimum quality of service * for these defaults requires confidentiality protection and server * authentication (that is, no anonymous cipher suites). + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -160,6 +167,13 @@ public abstract class SSLSocketFactory extends SocketFactory * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites are useful in specialized applications. + *

+ * The returned array includes cipher suites from the list of standard + * cipher suite names in the + * JSSE Cipher Suite Names section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @see #getDefaultCipherSuites() * @return an array of cipher suite names