Path: blob/master/test/jdk/java/net/URL/RacyHandler.java
41152 views
/*1* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.IOException;24import java.lang.reflect.*;25import java.net.URL;26import java.net.URLConnection;27import java.net.URLStreamHandler;28import java.util.concurrent.CountDownLatch;2930/*31* @test32* @bug 821394233* @summary URLStreamHandler initialization race34* @modules java.base/java.net:open35* @run main/othervm RacyHandler36* @run main/othervm RacyHandler37* @run main/othervm RacyHandler38*/3940/*41* This test makes reasonable effort to reproduce the race.42* Run repeatedly to ensure correctness.43*/44public class RacyHandler {45static volatile boolean factorySet = false;46static int NUM_THREADS = 2;47static CountDownLatch cdl = new CountDownLatch(NUM_THREADS + 1);4849public static void main(String[] args) {50RacyHandler tester = new RacyHandler();51tester.runTest();52}5354public void runTest() {55new Thread(() -> {56try {57cdl.await();58URL.setURLStreamHandlerFactory(proto -> new CustomHttpHandler());59factorySet = true;60} catch (Exception ignore) { }61}).start();62cdl.countDown();6364for (int i = 0; i < NUM_THREADS; i++) {65new Thread(() -> {66try {67cdl.await();68while (!factorySet) {69// trigger URL class load70getURLStreamHandler();71}72} catch (Exception ignore) { }73}).start();74cdl.countDown();75}7677// wait for the factory to be set78while (!factorySet) { }79// The sleep seems to help trigger the failure80try {81Thread.sleep(500);82} catch (InterruptedException ie) {83}8485URLStreamHandler httpHandler = getURLStreamHandler();86System.out.println("After setting factory URL handlers: http " + httpHandler);87if (!(httpHandler instanceof CustomHttpHandler))88throw new RuntimeException("FAILED: Incorrect handler type");89}9091/*92* This is just so we can see what we get for the URLStreamHandler back93* from the factory to verify whether it really is using our Handler94* or something else...95*/96public URLStreamHandler getURLStreamHandler() {97try {98Method method = URL.class.getDeclaredMethod("getURLStreamHandler",99String.class);100method.setAccessible(true);101return (URLStreamHandler) method.invoke(null, "http");102} catch (Exception e) {103return null;104}105}106107class CustomHttpHandler extends URLStreamHandler {108@Override109protected URLConnection openConnection(URL u) throws IOException {110return null;111}112}113}114115116