Skip to content

Commit 620250b

Browse files
committed
8317965: TestLoadLibraryDeadlock.java fails with "Unable to load native library.: expected true, was false"
8319265: TestLoadLibraryDeadlock.java fails on windows-x64 "Unable to load b.jar" Backport-of: 5207443b360cfe3ee9c53ece55da3464c13f6a9f
1 parent d2c6be9 commit 620250b

File tree

2 files changed

+45
-91
lines changed

2 files changed

+45
-91
lines changed

test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/LoadLibraryDeadlock.java

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2021, BELLSOFT. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -33,16 +33,19 @@
3333
* triggered from JNI.
3434
*/
3535
import java.lang.*;
36+
import java.net.URISyntaxException;
3637

3738
public class LoadLibraryDeadlock {
3839

3940
public static void main(String[] args) {
41+
System.out.println("LoadLibraryDeadlock test started");
4042
Thread t1 = new Thread() {
4143
public void run() {
4244
try {
4345
// an instance of unsigned class that loads a native library
4446
Class<?> c1 = Class.forName("Class1");
4547
Object o = c1.newInstance();
48+
System.out.println("Class1 loaded from " + getLocation(c1));
4649
} catch (ClassNotFoundException |
4750
InstantiationException |
4851
IllegalAccessException e) {
@@ -56,7 +59,7 @@ public void run() {
5659
try {
5760
// load a class from a signed jar, which locks the JarFile
5861
Class<?> c2 = Class.forName("p.Class2");
59-
System.out.println("Signed jar loaded.");
62+
System.out.println("Class2 loaded from " + getLocation(c2));
6063
} catch (ClassNotFoundException e) {
6164
System.out.println("Class Class2 not found.");
6265
throw new RuntimeException(e);
@@ -68,7 +71,19 @@ public void run() {
6871
try {
6972
t1.join();
7073
t2.join();
71-
} catch (InterruptedException ignore) {
74+
} catch (InterruptedException ex) {
75+
throw new RuntimeException(ex);
76+
}
77+
}
78+
79+
private static String getLocation(Class<?> c) {
80+
var pd = c.getProtectionDomain();
81+
var cs = pd != null ? pd.getCodeSource() : null;
82+
try {
83+
// same format as returned by TestLoadLibraryDeadlock::getLocation
84+
return cs != null ? cs.getLocation().toURI().getPath() : null;
85+
} catch (URISyntaxException ex) {
86+
throw new RuntimeException(ex);
7287
}
7388
}
7489
}

test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/TestLoadLibraryDeadlock.java

+27-88
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2021, BELLSOFT. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -38,13 +38,14 @@
3838
import jdk.test.lib.util.FileUtils;
3939

4040
import java.lang.ProcessBuilder;
41-
import java.lang.Process;
41+
import java.nio.file.Path;
4242
import java.nio.file.Paths;
4343
import java.io.*;
4444
import java.util.*;
45-
import java.util.concurrent.*;
4645
import java.util.spi.ToolProvider;
4746

47+
import static jdk.test.lib.process.ProcessTools.*;
48+
4849
public class TestLoadLibraryDeadlock {
4950

5051
private static final ToolProvider JAR = ToolProvider.findFirst("jar")
@@ -108,76 +109,24 @@ private static OutputAnalyzer signJar(String jarToSign) throws Throwable {
108109
);
109110
}
110111

111-
private static Process runJavaCommand(String... command) throws Throwable {
112-
String java = JDKToolFinder.getJDKTool("java");
113-
List<String> commands = new ArrayList<>();
114-
Collections.addAll(commands, java);
115-
Collections.addAll(commands, command);
116-
System.out.println("COMMAND: " + String.join(" ", commands));
117-
return new ProcessBuilder(commands.toArray(new String[0]))
118-
.redirectErrorStream(true)
119-
.directory(new File(testClassPath))
120-
.start();
121-
}
122-
123-
private static OutputAnalyzer jcmd(long pid, String command) throws Throwable {
124-
String jcmd = JDKToolFinder.getJDKTool("jcmd");
125-
return runCommandInTestClassPath(jcmd,
126-
String.valueOf(pid),
127-
command
128-
);
129-
}
130-
131-
private static String readAvailable(final InputStream is) throws Throwable {
132-
final List<String> list = Collections.synchronizedList(new ArrayList<String>());
133-
ExecutorService executor = Executors.newFixedThreadPool(2);
134-
Future<String> future = executor.submit(new Callable<String>() {
135-
public String call() {
136-
String result = new String();
137-
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
138-
try {
139-
while(true) {
140-
String s = reader.readLine();
141-
if (s.length() > 0) {
142-
list.add(s);
143-
result += s + "\n";
144-
}
145-
}
146-
} catch (IOException ignore) {}
147-
return result;
148-
}
149-
});
150-
try {
151-
return future.get(1000, TimeUnit.MILLISECONDS);
152-
} catch (Exception ignoreAll) {
153-
future.cancel(true);
154-
return String.join("\n", list);
155-
}
156-
}
157-
158112
private final static long countLines(OutputAnalyzer output, String string) {
159113
return output.asLines()
160114
.stream()
161115
.filter(s -> s.contains(string))
162116
.count();
163117
}
164118

165-
private final static void dump(OutputAnalyzer output) {
166-
output.asLines()
167-
.stream()
168-
.forEach(s -> System.out.println(s));
169-
}
170-
171119
public static void main(String[] args) throws Throwable {
172120
genKey()
173121
.shouldHaveExitValue(0);
174122

175-
FileUtils.deleteFileIfExistsWithRetry(
176-
Paths.get(testClassPath, "a.jar"));
177-
FileUtils.deleteFileIfExistsWithRetry(
178-
Paths.get(testClassPath, "b.jar"));
179-
FileUtils.deleteFileIfExistsWithRetry(
180-
Paths.get(testClassPath, "c.jar"));
123+
Path aJar = Path.of(testClassPath, "a.jar");
124+
Path bJar = Path.of(testClassPath, "b.jar");
125+
Path cJar = Path.of(testClassPath, "c.jar");
126+
127+
FileUtils.deleteFileIfExistsWithRetry(aJar);
128+
FileUtils.deleteFileIfExistsWithRetry(bJar);
129+
FileUtils.deleteFileIfExistsWithRetry(cJar);
181130

182131
createJar("a.jar",
183132
"LoadLibraryDeadlock.class",
@@ -194,24 +143,13 @@ public static void main(String[] args) throws Throwable {
194143
.shouldHaveExitValue(0);
195144

196145
// load trigger class
197-
Process process = runJavaCommand("-cp",
198-
"a.jar" + classPathSeparator +
199-
"b.jar" + classPathSeparator +
200-
"c.jar",
146+
OutputAnalyzer outputAnalyzer = executeCommand(createTestJavaProcessBuilder("-cp",
147+
aJar.toString() + classPathSeparator +
148+
bJar.toString() + classPathSeparator +
149+
cJar.toString(),
201150
"-Djava.library.path=" + testLibraryPath,
202-
"LoadLibraryDeadlock");
203-
204-
// wait for a while to grab some output
205-
process.waitFor(5, TimeUnit.SECONDS);
206-
207-
// dump available output
208-
String output = readAvailable(process.getInputStream());
209-
OutputAnalyzer outputAnalyzer = new OutputAnalyzer(output);
210-
dump(outputAnalyzer);
211-
212-
// if the process is still running, get the thread dump
213-
OutputAnalyzer outputAnalyzerJcmd = jcmd(process.pid(), "Thread.print");
214-
dump(outputAnalyzerJcmd);
151+
"LoadLibraryDeadlock"));
152+
outputAnalyzer.shouldHaveExitValue(0);
215153

216154
Asserts.assertTrue(
217155
countLines(outputAnalyzer, "Java-level deadlock") == 0,
@@ -231,19 +169,20 @@ public static void main(String[] args) throws Throwable {
231169
"Unable to load native library.");
232170

233171
Asserts.assertTrue(
234-
countLines(outputAnalyzer, "Signed jar loaded.") > 0,
235-
"Unable to load signed jar.");
172+
countLines(outputAnalyzer, "Class1 loaded from " + toLocationString(bJar)) > 0,
173+
"Unable to load " + toLocationString(bJar));
174+
175+
Asserts.assertTrue(
176+
countLines(outputAnalyzer, "Class2 loaded from " + toLocationString(cJar)) > 0,
177+
"Unable to load signed " + toLocationString(cJar));
236178

237179
Asserts.assertTrue(
238180
countLines(outputAnalyzer, "Signed jar loaded from native library.") > 0,
239181
"Unable to load signed jar from native library.");
182+
}
240183

241-
if (!process.waitFor(5, TimeUnit.SECONDS)) {
242-
// if the process is still frozen, fail the test even though
243-
// the "deadlock" text hasn't been found
244-
process.destroyForcibly();
245-
Asserts.assertTrue(process.waitFor() == 0,
246-
"Process frozen.");
247-
}
184+
private static String toLocationString(Path path) {
185+
// same format as returned by LoadLibraryDeadlock::getLocation
186+
return path.toUri().getPath();
248187
}
249188
}

0 commit comments

Comments
 (0)