1 /* 2 * Copyright (c) 2018, Amazon and/or its affiliates. All rights reserved. 3 * Copyright (c) 2019, Azul Systems, Inc. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /** 26 * @test 27 * @bug 8231584 28 * @library /test/lib 29 * @run main/othervm LoadLibraryTest 30 */ 31 32 import java.nio.file.FileSystems; 33 import java.nio.file.Files; 34 import java.nio.file.Paths; 35 import java.nio.file.Path; 36 import java.net.MalformedURLException; 37 import java.net.URLClassLoader; 38 import java.net.URL; 39 40 import jdk.test.lib.compiler.CompilerUtils; 41 42 public class LoadLibraryTest { 43 static Thread thread1 = null; 44 static Thread thread2 = null; 45 46 static volatile boolean thread1Ready = false; 47 48 private static final String TEST_SRC = System.getProperty("test.src"); 49 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 50 private static final Path CLS_DIR = Paths.get("classes"); 51 52 static TestClassLoader loader; someLibLoad()53 static void someLibLoad() { 54 try { 55 /* 56 FileSystems.getDefault(); 57 58 // jdk/jdk: loads directly from Bootstrap Classloader (doesn't take lock on Runtime) 59 java.net.NetworkInterface.getNetworkInterfaces(); 60 61 System.out.println(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); 62 */ 63 Class c = Class.forName("Target2", true, loader); 64 } catch (Exception e) { 65 throw new RuntimeException(e); 66 } 67 } 68 69 static class TestClassLoader extends URLClassLoader { 70 boolean passed = false; 71 passed()72 public boolean passed() { 73 return passed; 74 } 75 TestClassLoader()76 TestClassLoader() throws MalformedURLException { 77 super(new URL[] { new URL("file://" + CLS_DIR.toAbsolutePath().toString() + '/') }); 78 } 79 findLibrary(String name)80 public String findLibrary(String name) { 81 System.out.println("findLibrary " + name); 82 83 if ("someLibrary".equals(name)) { 84 try { 85 synchronized(thread1) { 86 while(!thread1Ready) { 87 thread1.wait(); 88 } 89 thread1.notifyAll(); 90 } 91 92 Thread.sleep(10000); 93 94 System.out.println("Thread2 load"); 95 someLibLoad(); 96 97 // no deadlock happened 98 passed = true; 99 } catch (Exception e) { 100 throw new RuntimeException(e); 101 } 102 return null; 103 } 104 105 return super.findLibrary(name); 106 } 107 } 108 109 main(String[] args)110 public static void main(String[] args) throws Exception { 111 loader = new TestClassLoader(); 112 113 if (!CompilerUtils.compile(SRC_DIR, CLS_DIR)) { 114 throw new Exception("Can't compile"); 115 } 116 117 thread1 = new Thread() { 118 public void run() { 119 try { 120 synchronized(this) { 121 thread1Ready = true; 122 thread1.notifyAll(); 123 thread1.wait(); 124 } 125 } catch(InterruptedException e) { 126 throw new RuntimeException(e); 127 } 128 129 System.out.println("Thread1 load"); 130 someLibLoad(); 131 }; 132 }; 133 134 thread2 = new Thread() { 135 public void run() { 136 try { 137 Class c = Class.forName("Target", true, loader); 138 System.out.println(c); 139 } catch (Exception e) { 140 throw new RuntimeException(e); 141 } 142 }; 143 }; 144 145 thread1.setDaemon(true); 146 thread2.setDaemon(true); 147 148 thread1.start(); 149 thread2.start(); 150 151 thread1.join(); 152 thread2.join(); 153 154 if (!loader.passed()) { 155 throw new RuntimeException("FAIL"); 156 } 157 } 158 } 159