changeset 7208:8e79fcdbf9ec

Merge
author lana
date Mon, 12 May 2014 17:09:39 -0700
parents 8fe3cb32ff83 b7b7ed1d003b
children 4645fadf8352
files test/java/awt/Toolkit/ToolkitPropertyTest/NoAppContextTest.java
diffstat 14 files changed, 629 insertions(+), 215 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Apr 28 09:37:23 2014 -0700
+++ b/.hgtags	Mon May 12 17:09:39 2014 -0700
@@ -420,3 +420,7 @@
 b06d4ed71ae0bc6e13f5a8437cb6388f17c66e84 jdk7u60-b13
 b7fbd9b4febf8961091fdf451d3da477602a8f1d jdk7u60-b14
 04882f9a073e8de153ec7ad32486569fd9a087ec jdk7u60-b15
+41547583c3a035c3924ffedfa8704e58d69e5c50 jdk7u60-b16
+e484202d9a4104840d758a21b2bba1250e766343 jdk7u60-b18
+e484202d9a4104840d758a21b2bba1250e766343 jdk7u60-b17
+7190843ddaf4f3ad158c3071be0f4ca42a5802dc jdk7u60-b19
--- a/make/bridge/Jabswitch/Makefile	Mon Apr 28 09:37:23 2014 -0700
+++ b/make/bridge/Jabswitch/Makefile	Mon May 12 17:09:39 2014 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,10 @@
 JAB_MANIFEST_INP = $(CLOSED_PLATFORM_SRC)/native/sun/bridge/jabswitch.manifest
 JAB_MANIFEST_OUT = $(TEMPDIR)/jabswitch.exe.intermediate.manifest
 
-RC_FLAGS += /fo "$(VERSIONRES)"
+RC_FLAGS += /fo "$(VERSIONRES)" \
+            /D "JDK_FNAME=$(PROGRAM)$(EXE_SUFFIX)" \
+            /D "JDK_INTERNAL_NAME=$(PROGRAM)" \
+            /D "JDK_FTYPE=0x1L"
 OTHER_CPPFLAGS += /MD /Fo"$(TEMPDIR)/" /Fd"$(TEMPDIR)/" /analyze- /Od /Gd /nologo /Gm /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /RTC1 /W3 /ZI /Zc:wchar_t /EHsc 
 LDDFLAGS += Advapi32.lib Version.lib User32.lib
 
--- a/make/com/apple/osxui/Makefile	Mon Apr 28 09:37:23 2014 -0700
+++ b/make/com/apple/osxui/Makefile	Mon May 12 17:09:39 2014 -0700
@@ -67,6 +67,7 @@
 
 RESOURCE_BUNDLES_COMPILED_PROPERTIES += \
 	com/apple/laf/resources/aqua.properties
+LOCALE_SET_DEFINITION = jre
 
 #
 # Rules
--- a/make/common/internal/Resources.gmk	Mon Apr 28 09:37:23 2014 -0700
+++ b/make/common/internal/Resources.gmk	Mon May 12 17:09:39 2014 -0700
@@ -225,6 +225,10 @@
 	$(add-property-java-file)
 $(GENSRCDIR)/%_zh_HK.java: $(SHARE_SRC)/classes/%_zh_TW.properties
 	$(add-property-java-file)
+ifdef PLATFORM_SRC_MACOS
+$(GENSRCDIR)/%_zh_HK.java: $(PLATFORM_SRC_MACOS)/classes/%_zh_TW.properties
+	$(add-property-java-file)
+endif
 
 # Simple delivery of zh_HK properties files just copies zh_TW properties files
 $(CLASSDESTDIR)/%_zh_HK.properties: \
--- a/make/sun/security/krb5/Makefile	Mon Apr 28 09:37:23 2014 -0700
+++ b/make/sun/security/krb5/Makefile	Mon May 12 17:09:39 2014 -0700
@@ -92,7 +92,7 @@
   OTHER_LDLIBS = $(LIBDL) $(JVMLIB)
 endif
 
-build:
+all:
 ifeq ($(PLATFORM),windows)
 	$(call make-launcher, kinit, sun.security.krb5.internal.tools.Kinit, , )
 	$(call make-launcher, klist, sun.security.krb5.internal.tools.Klist, , )
--- a/src/share/classes/java/awt/event/MouseEvent.java	Mon Apr 28 09:37:23 2014 -0700
+++ b/src/share/classes/java/awt/event/MouseEvent.java	Mon May 12 17:09:39 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -758,7 +758,6 @@
 
             if (getModifiersEx() != 0) { //There is at least one more button in a pressed state.
                 if (id == MouseEvent.MOUSE_RELEASED || id == MouseEvent.MOUSE_CLICKED){
-                    System.out.println("MEvent. CASE!");
                     shouldExcludeButtonFromExtModifiers = true;
                 }
             }
--- a/src/share/classes/javax/accessibility/AccessibleContext.java	Mon Apr 28 09:37:23 2014 -0700
+++ b/src/share/classes/javax/accessibility/AccessibleContext.java	Mon May 12 17:09:39 2014 -0700
@@ -25,6 +25,9 @@
 
 package javax.accessibility;
 
+import sun.awt.AWTAccessor;
+import sun.awt.AppContext;
+
 import java.util.Locale;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
@@ -79,6 +82,26 @@
  */
 public abstract class AccessibleContext {
 
+    /**
+     * The AppContext that should be used to dispatch events for this
+     * AccessibleContext
+     */
+    private volatile AppContext targetAppContext;
+
+    static {
+        AWTAccessor.setAccessibleContextAccessor(new AWTAccessor.AccessibleContextAccessor() {
+            @Override
+            public void setAppContext(AccessibleContext accessibleContext, AppContext appContext) {
+                accessibleContext.targetAppContext = appContext;
+            }
+
+            @Override
+            public AppContext getAppContext(AccessibleContext accessibleContext) {
+                return accessibleContext.targetAppContext;
+            }
+        });
+    }
+
    /**
     * Constant used to determine when the accessibleName property has
     * changed.  The old value in the PropertyChangeEvent will be the old
--- a/src/share/classes/javax/swing/JComponent.java	Mon Apr 28 09:37:23 2014 -0700
+++ b/src/share/classes/javax/swing/JComponent.java	Mon May 12 17:09:39 2014 -0700
@@ -3989,6 +3989,17 @@
          * @since 1.4
          */
         public AccessibleKeyBinding getAccessibleKeyBinding() {
+            // Try to get the linked label's mnemonic if it exists
+            Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
+            if (o instanceof Accessible){
+                AccessibleContext ac = ((Accessible) o).getAccessibleContext();
+                if (ac != null){
+                    AccessibleComponent comp = ac.getAccessibleComponent();
+                    if (! (comp instanceof AccessibleExtendedComponent))
+                        return null;
+                    return ((AccessibleExtendedComponent)comp).getAccessibleKeyBinding();
+                }
+            }
             return null;
         }
     } // inner class AccessibleJComponent
--- a/src/share/classes/sun/awt/AWTAccessor.java	Mon Apr 28 09:37:23 2014 -0700
+++ b/src/share/classes/sun/awt/AWTAccessor.java	Mon May 12 17:09:39 2014 -0700
@@ -25,6 +25,7 @@
 
 package sun.awt;
 
+import javax.accessibility.AccessibleContext;
 import java.awt.*;
 import java.awt.KeyboardFocusManager;
 import java.awt.DefaultKeyboardFocusManager;
@@ -723,6 +724,14 @@
 
 
     /*
+     * An accessor object for the AccessibleContext class
+     */
+    public interface AccessibleContextAccessor {
+        void setAppContext(AccessibleContext accessibleContext, AppContext appContext);
+        AppContext getAppContext(AccessibleContext accessibleContext);
+    }
+
+    /*
      * Accessor instances are initialized in the static initializers of
      * corresponding AWT classes by using setters defined below.
      */
@@ -751,6 +760,7 @@
     private static SequencedEventAccessor sequencedEventAccessor;
     private static InvocationEventAccessor invocationEventAccessor;
     private static ToolkitAccessor toolkitAccessor;
+    private static AccessibleContextAccessor accessibleContextAccessor;
 
     /*
      * Set an accessor object for the java.awt.Component class.
@@ -1177,4 +1187,22 @@
     public static InvocationEventAccessor getInvocationEventAccessor() {
         return invocationEventAccessor;
     }
+
+
+    /*
+     * Get the accessor object for the javax.accessibility.AccessibleContext class.
+     */
+    public static AccessibleContextAccessor getAccessibleContextAccessor() {
+        if (accessibleContextAccessor == null) {
+            unsafe.ensureClassInitialized(AccessibleContext.class);
+        }
+        return accessibleContextAccessor;
+    }
+
+    /*
+     * Set the accessor object for the javax.accessibility.AccessibleContext class.
+     */
+    public static void setAccessibleContextAccessor(AccessibleContextAccessor accessor) {
+        AWTAccessor.accessibleContextAccessor = accessor;
+    }
 }
--- a/src/share/classes/sun/net/www/http/HttpClient.java	Mon Apr 28 09:37:23 2014 -0700
+++ b/src/share/classes/sun/net/www/http/HttpClient.java	Mon May 12 17:09:39 2014 -0700
@@ -651,7 +651,9 @@
                     // try once more
                     openServer();
                     if (needsTunneling()) {
+                        MessageHeader origRequests = requests;
                         httpuc.doTunneling();
+                        requests = origRequests;
                     }
                     afterConnect();
                     writeRequests(requests, poster);
@@ -762,7 +764,9 @@
                         cachedHttpClient = false;
                         openServer();
                         if (needsTunneling()) {
+                            MessageHeader origRequests = requests;
                             httpuc.doTunneling();
+                            requests = origRequests;
                         }
                         afterConnect();
                         writeRequests(requests, poster);
--- a/src/windows/classes/sun/awt/windows/WToolkit.java	Mon Apr 28 09:37:23 2014 -0700
+++ b/src/windows/classes/sun/awt/windows/WToolkit.java	Mon May 12 17:09:39 2014 -0700
@@ -864,18 +864,12 @@
      * Windows doesn't always send WM_SETTINGCHANGE when it should.
      */
     private void windowsSettingChange() {
-        if (AppContext.getAppContext() == null) {
-            // No AppContext, so we can update properties on the current thread,
-            // DesktopPropertyChangeSupport will only post events.
-            updateProperties();
-        } else {
-            EventQueue.invokeLater(new Runnable() {
-                @Override
-                public void run() {
-                    updateProperties();
-                }
-            });
-        }
+        EventQueue.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                updateProperties();
+            }
+        });
     }
 
     private synchronized void updateProperties() {
--- a/test/java/awt/Toolkit/ToolkitPropertyTest/NoAppContextTest.java	Mon Apr 28 09:37:23 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 8032960
- * @summary checks that desktop properties work if Toolkit thread has no AppContext
- * @author Petr Pchelko
- */
-
-import sun.awt.OSInfo;
-import sun.awt.SunToolkit;
-
-import javax.swing.*;
-import java.awt.*;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-public class NoAppContextTest {
-
-    private static final ThreadGroup stubGroup = new ThreadGroup("stub");
-    private static final ThreadGroup awtGroup = new ThreadGroup("AWT");
-    private static final AtomicBoolean propertyChangeFired = new AtomicBoolean(false);
-    private static Frame frame;
-
-    private static final Object LOCK = new Object();
-
-    public static void main(String[] args) throws Exception {
-
-        if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
-            // The test is for Windows platform only
-            return;
-        }
-
-        createStubContext();
-
-        Thread awtThread = new Thread(awtGroup, new Runnable() {
-            @Override
-            public void run() {
-                SunToolkit.createNewAppContext();
-                SwingUtilities.invokeLater(new Runnable() {
-                    @Override
-                    public void run() {
-                        synchronized (LOCK) {
-                            frame = new Frame();
-                            frame.setBounds(100, 100, 100, 100);
-                            frame.setVisible(true);
-                            Toolkit.getDefaultToolkit().addPropertyChangeListener("win.propNames", new PropertyChangeListener() {
-                                @Override
-                                public void propertyChange(PropertyChangeEvent ev) {
-                                    propertyChangeFired.set(true);
-                                }
-                            });
-                        }
-                    }
-                });
-            }
-        });
-        awtThread.start();
-        awtThread.join();
-        sync();
-
-        final GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment()
-                .getDefaultScreenDevice();
-
-        final AtomicReference<DisplayMode> originalRef = new AtomicReference<>();
-        try {
-            final AtomicBoolean isSupported = new AtomicBoolean(true);
-            invokeInAWT(new Runnable() {
-                @Override
-                public void run() {
-                    if (device.isFullScreenSupported()) {
-                        device.setFullScreenWindow(frame);
-                    } else {
-                        isSupported.set(false);
-                    }
-                }
-            });
-            if (!isSupported.get()) {
-                return;
-            }
-            invokeInAWT(new Runnable() {
-                @Override
-                public void run() {
-                    if (device.isDisplayChangeSupported()) {
-                        DisplayMode original = device.getDisplayMode();
-                        originalRef.set(original);
-                        try {
-                            DisplayMode[] modes = device.getDisplayModes();
-                            for (DisplayMode mode : modes) {
-                                if (!mode.equals(original)) {
-                                    device.setDisplayMode(mode);
-                                    break;
-                                }
-                            }
-                        } finally {
-                            device.setDisplayMode(original);
-                        }
-                    } else {
-                        isSupported.set(false);
-                    }
-                }
-            });
-            if (!isSupported.get()) {
-                return;
-            }
-        } finally {
-            invokeInAWT(new Runnable() {
-                @Override
-                public void run() {
-                    device.setDisplayMode(originalRef.get());
-                    frame.dispose();
-                }
-            });
-        }
-
-        if (!propertyChangeFired.get()) {
-            throw new RuntimeException("Failed: PropertyChange did not fire");
-        }
-    }
-
-    private static void invokeInAWT(final Runnable r) throws InterruptedException {
-        Thread awtThread = new Thread(awtGroup, new Runnable() {
-            @Override
-            public void run() {
-                SwingUtilities.invokeLater(new Runnable() {
-                    @Override
-                    public void run() {
-                        synchronized (LOCK) {
-                            r.run();
-                        }
-                    }
-                });
-            }
-        });
-        awtThread.start();
-        awtThread.join();
-        sync();
-    }
-
-    private static void createStubContext() throws InterruptedException {
-        Thread stub = new Thread(stubGroup, new Runnable() {
-            @Override
-            public void run() {
-                SunToolkit.createNewAppContext();
-            }
-        });
-        stub.start();
-        stub.join();
-    }
-
-    /**
-     * Runs realSync on a thread with an AppContext and waits for it to finish
-     */
-    private static void sync() throws InterruptedException {
-        final AtomicReference<InterruptedException> exc = new AtomicReference<>(null);
-
-        Thread syncThread = new Thread(awtGroup, new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
-                    Thread.sleep(2000);
-                } catch (InterruptedException e) {
-                    exc.set(e);
-                }
-            }
-        });
-        syncThread.start();
-        syncThread.join();
-        if (exc.get() != null) {
-            throw exc.get();
-        }
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/JTextField/8036819/bug8036819.java	Mon May 12 17:09:39 2014 -0700
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library ../../regtesthelpers
+ * @build Util
+ * @bug 8036819
+ * @summary JAB: mnemonics not read for textboxes
+ * @author Vivi An
+ * @run main bug8036819
+ */
+
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import sun.awt.SunToolkit;
+import javax.accessibility.*;
+
+public class bug8036819 {
+
+    public static volatile Boolean passed = false;
+
+    public static void main(String args[]) throws Throwable {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                createAndShowGUI();
+            }
+        });
+
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        toolkit.realSync();
+
+        Robot robo = new Robot();
+        robo.setAutoDelay(300);
+
+        // Using mnemonic key to focus on the textfield
+        Util.hitMnemonics(robo, KeyEvent.VK_P);
+        toolkit.realSync();
+
+        if (!passed){
+            throw new RuntimeException("Test failed.");
+        }
+    }
+
+    private static void createAndShowGUI() {
+        JFrame mainFrame = new JFrame("bug 8036819");
+
+        JLabel usernameLabel = new JLabel("Username: ");
+        JTextField usernameField = new JTextField(20);
+        usernameLabel.setDisplayedMnemonic(KeyEvent.VK_U);
+        usernameLabel.setLabelFor(usernameField);
+
+        JLabel pwdLabel = new JLabel("Password: ");
+        JTextField pwdField = new JTextField(20);
+        pwdLabel.setDisplayedMnemonic(KeyEvent.VK_P);
+        pwdLabel.setLabelFor(pwdField);
+
+        pwdField.addKeyListener(
+            new KeyListener(){
+                @Override
+                public void keyPressed(KeyEvent keyEvent) {
+                }
+
+                @Override
+                public void keyTyped(KeyEvent keyEvent) {
+                }
+
+                @Override
+                public void keyReleased(KeyEvent keyEvent){
+                    JComponent comp = (JComponent) pwdField;
+                    AccessibleContext ac = comp.getAccessibleContext();
+                    AccessibleExtendedComponent aec = (AccessibleExtendedComponent)ac.getAccessibleComponent();
+                    AccessibleKeyBinding akb = aec.getAccessibleKeyBinding();
+                    if (akb != null){
+                         int count = akb.getAccessibleKeyBindingCount();
+                        if (count != 1){
+                            passed = false;
+                            return;
+                        }
+
+                        // there is 1 accessible key for the text field
+                        System.out.println("Retrieved AccessibleKeyBinding for textfield " + count);
+
+                        // the key code is KeyEvent.VK_P
+                        Object o = akb.getAccessibleKeyBinding(0);
+                        if (o instanceof KeyStroke){
+                            javax.swing.KeyStroke key = (javax.swing.KeyStroke)o;
+                            System.out.println("keystroke is " + key.getKeyCode());
+                            if (key.getKeyCode() == KeyEvent.VK_P)
+                                passed = true;
+                        }
+                    }
+                }
+            }
+        );
+
+        mainFrame.getContentPane().add(usernameLabel);
+        mainFrame.getContentPane().add(usernameField);
+        mainFrame.getContentPane().add(pwdLabel);
+        mainFrame.getContentPane().add(pwdField);
+
+        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        mainFrame.setLayout(new FlowLayout(FlowLayout.LEFT));
+
+        mainFrame.setSize(200, 200);
+        mainFrame.setLocation(200, 200);
+        mainFrame.setVisible(true);
+        mainFrame.toFront();
+    }
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/net/www/http/HttpClient/B8025710.java	Mon May 12 17:09:39 2014 -0700
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import javax.net.ssl.*;
+
+/**
+ * @test
+ * @bug 8025710
+ * @summary Proxied https connection reuse by HttpClient can send CONNECT to the server
+ */
+public class B8025710 {
+
+    private final static AtomicBoolean connectInServer = new AtomicBoolean();
+    private static final String keystorefile =
+            System.getProperty("test.src", "./")
+            + "/../../../../../sun/security/ssl/etc/keystore";
+    private static final String passphrase = "passphrase";
+
+    public static void main(String[] args) throws Exception {
+        new B8025710().runTest();
+
+        if (connectInServer.get())
+            throw new RuntimeException("TEST FAILED: server got proxy header");
+        else
+            System.out.println("TEST PASSED");
+    }
+
+    private void runTest() throws Exception {
+        ProxyServer proxyServer = new ProxyServer();
+        HttpServer httpServer = new HttpServer();
+        httpServer.start();
+        proxyServer.start();
+
+        URL url = new URL("https", InetAddress.getLocalHost().getHostName(),
+                httpServer.getPort(), "/");
+
+        Proxy proxy = new Proxy(Proxy.Type.HTTP, proxyServer.getAddress());
+
+        HttpsURLConnection.setDefaultSSLSocketFactory(createTestSSLSocketFactory());
+
+        // Make two connections. The bug occurs when the second request is made
+        for (int i = 0; i < 2; i++) {
+            System.out.println("Client: Requesting " + url.toExternalForm()
+                    + " via " + proxy.toString()
+                    + " (attempt " + (i + 1) + " of 2)");
+
+            HttpsURLConnection connection =
+                    (HttpsURLConnection) url.openConnection(proxy);
+
+            connection.setRequestMethod("POST");
+            connection.setDoInput(true);
+            connection.setDoOutput(true);
+            connection.setRequestProperty("User-Agent", "Test/1.0");
+            connection.getOutputStream().write("Hello, world!".getBytes("UTF-8"));
+
+            if (connection.getResponseCode() != 200) {
+                System.err.println("Client: Unexpected response code "
+                        + connection.getResponseCode());
+                break;
+            }
+
+            String response = readLine(connection.getInputStream());
+            if (!"Hi!".equals(response)) {
+                System.err.println("Client: Unexpected response body: "
+                        + response);
+            }
+        }
+        httpServer.close();
+        proxyServer.close();
+        httpServer.join();
+        proxyServer.join();
+    }
+
+    class ProxyServer extends Thread implements Closeable {
+
+        private final ServerSocket proxySocket;
+        private final Pattern connectLinePattern =
+                Pattern.compile("^CONNECT ([^: ]+):([0-9]+) HTTP/[0-9.]+$");
+        private final String PROXY_RESPONSE =
+                "HTTP/1.0 200 Connection Established\r\n"
+                + "Proxy-Agent: TestProxy/1.0\r\n"
+                + "\r\n";
+
+        ProxyServer() throws Exception {
+            super("ProxyServer Thread");
+
+            // Create the http proxy server socket
+            proxySocket = ServerSocketFactory.getDefault().createServerSocket();
+            proxySocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+        }
+
+        public SocketAddress getAddress() { return  proxySocket.getLocalSocketAddress(); }
+
+        @Override
+        public void close() throws IOException {
+            proxySocket.close();
+        }
+
+        @Override
+        public void run() {
+            ArrayList<Thread> threads = new ArrayList<>();
+            int connectionCount = 0;
+            try {
+                while (connectionCount++ < 2) {
+                    final Socket clientSocket = proxySocket.accept();
+                    final int proxyConnectionCount = connectionCount;
+                    System.out.println("Proxy: NEW CONNECTION "
+                            + proxyConnectionCount);
+
+                    Thread t = new Thread("ProxySocket" + proxyConnectionCount) {
+                        @Override
+                        public void run() {
+                            try {
+                                String firstLine =
+                                        readHeader(clientSocket.getInputStream());
+
+                                Matcher connectLineMatcher =
+                                        connectLinePattern.matcher(firstLine);
+                                if (!connectLineMatcher.matches()) {
+                                    System.out.println("Proxy: Unexpected"
+                                            + " request to the proxy: "
+                                            + firstLine);
+                                    return;
+                                }
+
+                                String host    = connectLineMatcher.group(1);
+                                String portStr = connectLineMatcher.group(2);
+                                int port       = Integer.parseInt(portStr);
+
+                                Socket serverSocket = SocketFactory.getDefault()
+                                        .createSocket(host, port);
+
+                                clientSocket.getOutputStream()
+                                        .write(PROXY_RESPONSE.getBytes("UTF-8"));
+
+                                ProxyTunnel copyToClient =
+                                        new ProxyTunnel(serverSocket, clientSocket);
+                                ProxyTunnel copyToServer =
+                                        new ProxyTunnel(clientSocket, serverSocket);
+
+                                copyToClient.start();
+                                copyToServer.start();
+
+                                copyToClient.join();
+                                // here copyToClient.close() would not provoke the
+                                // bug ( since it would trigger the retry logic in
+                                // HttpURLConnction.writeRequests ), so close only
+                                // the output to get the connection in this state.
+                                clientSocket.shutdownOutput();
+
+                                try {
+                                    Thread.sleep(3000);
+                                } catch (InterruptedException ignored) { }
+
+                                // now close all connections to finish the test
+                                copyToServer.close();
+                                copyToClient.close();
+                            } catch (IOException | NumberFormatException
+                                    | InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    };
+                    threads.add(t);
+                    t.start();
+                }
+                for (Thread t: threads)
+                    t.join();
+            } catch (IOException | InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * This inner class provides unidirectional data flow through the sockets
+     * by continuously copying bytes from the input socket onto the output
+     * socket, until both sockets are open and EOF has not been received.
+     */
+    class ProxyTunnel extends Thread {
+        private final Socket sockIn;
+        private final Socket sockOut;
+        private final InputStream input;
+        private final OutputStream output;
+
+        public ProxyTunnel(Socket sockIn, Socket sockOut) throws IOException {
+            super("ProxyTunnel");
+            this.sockIn  = sockIn;
+            this.sockOut = sockOut;
+            input  = sockIn.getInputStream();
+            output = sockOut.getOutputStream();
+        }
+
+        public void run() {
+            byte[] buf = new byte[8192];
+            int bytesRead;
+
+            try {
+                while ((bytesRead = input.read(buf)) >= 0) {
+                    output.write(buf, 0, bytesRead);
+                    output.flush();
+                }
+            } catch (IOException ignored) {
+                close();
+            }
+        }
+
+        public void close() {
+            try {
+                if (!sockIn.isClosed())
+                    sockIn.close();
+                if (!sockOut.isClosed())
+                    sockOut.close();
+            } catch (IOException ignored) { }
+        }
+    }
+
+    /**
+     * the server thread
+     */
+    class HttpServer extends Thread implements Closeable {
+
+        private final ServerSocket serverSocket;
+        private final SSLSocketFactory sslSocketFactory;
+        private final String serverResponse =
+                "HTTP/1.1 200 OK\r\n"
+                + "Content-Type: text/plain\r\n"
+                + "Content-Length: 3\r\n"
+                + "\r\n"
+                + "Hi!";
+        private int connectionCount = 0;
+
+        HttpServer() throws Exception {
+            super("HttpServer Thread");
+
+            KeyStore ks = KeyStore.getInstance("JKS");
+            ks.load(new FileInputStream(keystorefile), passphrase.toCharArray());
+            KeyManagerFactory factory = KeyManagerFactory.getInstance("SunX509");
+            factory.init(ks, passphrase.toCharArray());
+            SSLContext ctx = SSLContext.getInstance("TLS");
+            ctx.init(factory.getKeyManagers(), null, null);
+
+            sslSocketFactory = ctx.getSocketFactory();
+
+            // Create the server that the test wants to connect to via the proxy
+            serverSocket = ServerSocketFactory.getDefault().createServerSocket();
+            serverSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+        }
+
+        public int getPort() { return  serverSocket.getLocalPort(); }
+
+        @Override
+        public void close() throws IOException { serverSocket.close(); }
+
+        @Override
+        public void run() {
+            try {
+                while (connectionCount++ < 2) {
+                    Socket socket = serverSocket.accept();
+                    System.out.println("Server: NEW CONNECTION "
+                            + connectionCount);
+
+                    SSLSocket sslSocket = (SSLSocket) sslSocketFactory
+                            .createSocket(socket,null, getPort(), false);
+                    sslSocket.setUseClientMode(false);
+                    sslSocket.startHandshake();
+
+                    String firstLine = readHeader(sslSocket.getInputStream());
+                    if (firstLine != null && firstLine.contains("CONNECT")) {
+                        System.out.println("Server: BUG! HTTP CONNECT"
+                                + " encountered: " + firstLine);
+                        connectInServer.set(true);
+                    }
+
+                    // write the success response, the request body is not read.
+                    // close only output and keep input open.
+                    OutputStream out = sslSocket.getOutputStream();
+                    out.write(serverResponse.getBytes("UTF-8"));
+                    socket.shutdownOutput();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * read the header and return only the first line.
+     *
+     * @param inputStream the stream to read from
+     * @return the first line of the stream
+     * @throws IOException if reading failed
+     */
+    private static String readHeader(InputStream inputStream)
+            throws IOException {
+        String line;
+        String firstLine = null;
+        while ((line = readLine(inputStream)) != null && line.length() > 0) {
+            if (firstLine == null) {
+                firstLine = line;
+            }
+        }
+
+        return firstLine;
+    }
+
+    /**
+     * read a line from stream.
+     *
+     * @param inputStream the stream to read from
+     * @return the line
+     * @throws IOException  if reading failed
+     */
+    private static String readLine(InputStream inputStream)
+            throws IOException {
+        final StringBuilder line = new StringBuilder();
+        int ch;
+        while ((ch = inputStream.read()) != -1) {
+            if (ch == '\r') {
+                continue;
+            }
+
+            if (ch == '\n') {
+                break;
+            }
+
+            line.append((char) ch);
+        }
+
+        return line.toString();
+    }
+
+    private SSLSocketFactory createTestSSLSocketFactory() {
+
+        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
+            @Override
+            public boolean verify(String hostname, SSLSession sslSession) {
+                // ignore the cert's CN; it's not important to this test
+                return true;
+            }
+        });
+
+        // Set up the socket factory to use a trust manager that trusts all
+        // certs, since trust validation isn't important to this test
+        final TrustManager[] trustAllCertChains = new TrustManager[] {
+            new X509TrustManager() {
+                @Override
+                public X509Certificate[] getAcceptedIssuers() {
+                    return null;
+                }
+
+                @Override
+                public void checkClientTrusted(X509Certificate[] certs,
+                        String authType) {
+                }
+
+                @Override
+                public void checkServerTrusted(X509Certificate[] certs,
+                        String authType) {
+                }
+            }
+        };
+
+        final SSLContext sc;
+        try {
+            sc = SSLContext.getInstance("TLS");
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+
+        try {
+            sc.init(null, trustAllCertChains, new java.security.SecureRandom());
+        } catch (KeyManagementException e) {
+            throw new RuntimeException(e);
+        }
+
+        return sc.getSocketFactory();
+    }
+}