1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 4910892
27 * @summary 4518403 was not properly fixed.   hashcode should be hashCode.
28 * @run main/othervm HashCodeMissing
29 *
30 *     SunJSSE does not support dynamic system properties, no way to re-use
31 *     system properties in samevm/agentvm mode.
32 * @author Brad Wetmore
33 */
34
35import java.io.*;
36import java.net.*;
37import javax.net.ssl.*;
38import java.lang.reflect.*;
39
40public class HashCodeMissing {
41
42    /*
43     * =============================================================
44     * Set the various variables needed for the tests, then
45     * specify what tests to run on each side.
46     */
47
48    /*
49     * Should we run the client or server in a separate thread?
50     * Both sides can throw exceptions, but do you have a preference
51     * as to which side should be the main thread.
52     */
53    static boolean separateServerThread = false;
54
55    /*
56     * Where do we find the keystores?
57     */
58    static String pathToStores = "../../../../javax/net/ssl/etc";
59    static String keyStoreFile = "keystore";
60    static String trustStoreFile = "truststore";
61    static String passwd = "passphrase";
62
63    /*
64     * Is the server ready to serve?
65     */
66    volatile static boolean serverReady = false;
67
68    /*
69     * Turn on SSL debugging?
70     */
71    static boolean debug = false;
72
73    /*
74     * If the client or server is doing some kind of object creation
75     * that the other side depends on, and that thread prematurely
76     * exits, you may experience a hang.  The test harness will
77     * terminate all hung threads after its timeout has expired,
78     * currently 3 minutes by default, but you might try to be
79     * smart about it....
80     */
81
82    /*
83     * Define the server side of the test.
84     *
85     * If the server prematurely exits, serverReady will be set to true
86     * to avoid infinite hangs.
87     */
88    void doServerSide() throws Exception {
89        SSLServerSocketFactory sslssf =
90            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
91        SSLServerSocket sslServerSocket =
92            (SSLServerSocket) sslssf.createServerSocket(serverPort);
93
94        serverPort = sslServerSocket.getLocalPort();
95
96        /*
97         * Signal Client, we're ready for his connect.
98         */
99        serverReady = true;
100
101        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
102        InputStream sslIS = sslSocket.getInputStream();
103        OutputStream sslOS = sslSocket.getOutputStream();
104
105        sslIS.read();
106        sslOS.write(85);
107        sslOS.flush();
108
109        sslSocket.close();
110    }
111
112    /*
113     * Define the client side of the test.
114     *
115     * If the server prematurely exits, serverReady will be set to true
116     * to avoid infinite hangs.
117     */
118    void doClientSide() throws Exception {
119
120        /*
121         * Wait for server to get started.
122         */
123        while (!serverReady) {
124            Thread.sleep(50);
125        }
126
127        SSLSocketFactory sslsf =
128            (SSLSocketFactory) SSLSocketFactory.getDefault();
129        SSLSocket sslSocket = (SSLSocket)
130            sslsf.createSocket("localhost", serverPort);
131
132        InputStream sslIS = sslSocket.getInputStream();
133        OutputStream sslOS = sslSocket.getOutputStream();
134
135        sslOS.write(280);
136        sslOS.flush();
137        sslIS.read();
138
139        SSLSession sslSession = sslSocket.getSession();
140
141        sslSocket.close();
142
143        Class clazz = sslSession.getClass();
144
145        /*
146         * Real test is done here
147         */
148        System.out.println("Getting 'hashCode'");
149        Method method = clazz.getDeclaredMethod("hashCode", new Class [0]);
150        System.out.println("Method = " + method);
151    }
152
153    /*
154     * =============================================================
155     * The remainder is just support stuff
156     */
157
158    // use any free port by default
159    volatile int serverPort = 0;
160
161    volatile Exception serverException = null;
162    volatile Exception clientException = null;
163
164    public static void main(String[] args) throws Exception {
165        String keyFilename =
166            System.getProperty("test.src", "./") + "/" + pathToStores +
167                "/" + keyStoreFile;
168        String trustFilename =
169            System.getProperty("test.src", "./") + "/" + pathToStores +
170                "/" + trustStoreFile;
171
172        System.setProperty("javax.net.ssl.keyStore", keyFilename);
173        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
174        System.setProperty("javax.net.ssl.trustStore", trustFilename);
175        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
176
177        if (debug)
178            System.setProperty("javax.net.debug", "all");
179
180        /*
181         * Start the tests.
182         */
183        new HashCodeMissing();
184    }
185
186    Thread clientThread = null;
187    Thread serverThread = null;
188
189    /*
190     * Primary constructor, used to drive remainder of the test.
191     *
192     * Fork off the other side, then do your work.
193     */
194    HashCodeMissing() throws Exception {
195        try {
196            if (separateServerThread) {
197                startServer(true);
198                startClient(false);
199            } else {
200                startClient(true);
201                startServer(false);
202            }
203        } catch (Exception e) {
204            //swallow for now.  Show later
205        }
206
207        /*
208         * Wait for other side to close down.
209         */
210        if (separateServerThread) {
211            serverThread.join();
212        } else {
213            clientThread.join();
214        }
215
216        /*
217         * When we get here, the test is pretty much over.
218         * Which side threw the error?
219         */
220        Exception local;
221        Exception remote;
222        String whichRemote;
223
224        if (separateServerThread) {
225            remote = serverException;
226            local = clientException;
227            whichRemote = "server";
228        } else {
229            remote = clientException;
230            local = serverException;
231            whichRemote = "client";
232        }
233
234        /*
235         * If both failed, return the curthread's exception, but also
236         * print the remote side Exception
237         */
238        if ((local != null) && (remote != null)) {
239            System.out.println(whichRemote + " also threw:");
240            remote.printStackTrace();
241            System.out.println();
242            throw local;
243        }
244
245        if (remote != null) {
246            throw remote;
247        }
248
249        if (local != null) {
250            throw local;
251        }
252    }
253
254    void startServer(boolean newThread) throws Exception {
255        if (newThread) {
256            serverThread = new Thread() {
257                public void run() {
258                    try {
259                        doServerSide();
260                    } catch (Exception e) {
261                        /*
262                         * Our server thread just died.
263                         *
264                         * Release the client, if not active already...
265                         */
266                        System.err.println("Server died...");
267                        serverReady = true;
268                        serverException = e;
269                    }
270                }
271            };
272            serverThread.start();
273        } else {
274            try {
275                doServerSide();
276            } catch (Exception e) {
277                serverException = e;
278            } finally {
279                serverReady = true;
280            }
281        }
282    }
283
284    void startClient(boolean newThread) throws Exception {
285        if (newThread) {
286            clientThread = new Thread() {
287                public void run() {
288                    try {
289                        doClientSide();
290                    } catch (Exception e) {
291                        /*
292                         * Our client thread just died.
293                         */
294                        System.err.println("Client died...");
295                        clientException = e;
296                    }
297                }
298            };
299            clientThread.start();
300        } else {
301            try {
302                doClientSide();
303            } catch (Exception e) {
304                clientException = e;
305            }
306        }
307    }
308}
309