11/*
2- * Copyright (c) 2019, 2020 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2019, 2021 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
@@ -97,21 +97,33 @@ public static void launch(String expectedMessage, String... toolArgs)
9797 launch (expectedMessage , Arrays .asList (toolArgs ));
9898 }
9999
100- public static void printStackTraces (String file ) throws IOException {
100+ /* Returns false if the attempt should be retried. */
101+ public static boolean printStackTraces (String file , boolean allowRetry ) throws IOException {
101102 try {
102103 String output = HprofReader .getStack (file , 0 );
103104 // We only require JShellToolProvider to be in the output if we did the
104105 // short sleep. If we did not, the java process may not have executed far
105106 // enough along to even start the main thread.
106107 if (doSleep && !output .contains ("JShellToolProvider" )) {
107- throw new RuntimeException ("'JShellToolProvider' missing from stdout/stderr" );
108+ // This check will very rarely fail due to not be able to get the stack trace
109+ // of the main thread do to it actively executing. See JDK-8269556. We retry once
110+ // if that happens. This failure is so rare that this should be enough to make it
111+ // extremely unlikely that we ever see this test fail again for this reason.
112+ if (!allowRetry ) {
113+ throw new RuntimeException ("'JShellToolProvider' missing from stdout/stderr" );
114+ } else {
115+ System .out .println ("'JShellToolProvider' missing. Allow one retry." );
116+ return true ; // Allow one retry
117+ }
108118 }
109119 } catch (Exception ex ) {
110120 throw new RuntimeException ("Test ERROR " + ex , ex );
111121 }
122+ return false ;
112123 }
113124
114- public static void testHeapDump () throws IOException {
125+ /* Returns false if the attempt should be retried. */
126+ public static boolean testHeapDump (boolean allowRetry ) throws IOException {
115127 File hprofFile = new File ("jhsdb.jmap.heap." +
116128 System .currentTimeMillis () + ".hprof" );
117129 if (hprofFile .exists ()) {
@@ -124,10 +136,12 @@ public static void testHeapDump() throws IOException {
124136 assertTrue (hprofFile .exists () && hprofFile .isFile (),
125137 "Could not create dump file " + hprofFile .getAbsolutePath ());
126138
127- printStackTraces (hprofFile .getAbsolutePath ());
139+ boolean retry = printStackTraces (hprofFile .getAbsolutePath (), allowRetry );
128140
129141 System .out .println ("hprof file size: " + hprofFile .length ());
130142 hprofFile .delete ();
143+
144+ return retry ;
131145 }
132146
133147 public static void launchJshell () throws IOException {
@@ -149,7 +163,7 @@ public static void launchJshell() throws IOException {
149163 // Give jshell a chance to fully start up. This makes SA more stable for the jmap dump.
150164 try {
151165 if (doSleep ) {
152- Thread .sleep (2000 );
166+ Thread .sleep (4000 );
153167 }
154168 } catch (Exception e ) {
155169 }
@@ -166,7 +180,12 @@ public static void main(String[] args) throws Exception {
166180 } else if (args .length != 0 ) {
167181 throw new RuntimeException ("Too many args: " + args .length );
168182 }
169- testHeapDump ();
183+
184+ boolean retry = testHeapDump (true );
185+ // In case of rare failure to find 'JShellToolProvider' in the output, allow one retry.
186+ if (retry ) {
187+ testHeapDump (false );
188+ }
170189
171190 // The test throws RuntimeException on error.
172191 // IOException is thrown if Jshell can't start because of some bad
0 commit comments