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 *
3838import jdk .test .lib .util .FileUtils ;
3939
4040import java .lang .ProcessBuilder ;
41- import java .lang . Process ;
41+ import java .nio . file . Path ;
4242import java .nio .file .Paths ;
4343import java .io .*;
4444import java .util .*;
45- import java .util .concurrent .*;
4645import java .util .spi .ToolProvider ;
4746
47+ import static jdk .test .lib .process .ProcessTools .*;
48+
4849public 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,15 @@ 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 " + bJar ) > 0 ,
173+ "Unable to load b.jar." );
174+
175+ Asserts .assertTrue (
176+ countLines (outputAnalyzer , "Class2 loaded from " + cJar ) > 0 ,
177+ "Unable to load signed c.jar." );
236178
237179 Asserts .assertTrue (
238180 countLines (outputAnalyzer , "Signed jar loaded from native library." ) > 0 ,
239181 "Unable to load signed jar from native library." );
240-
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- }
248182 }
249183}
0 commit comments