3636
3737import org .apache .commons .io .FileUtils ;
3838import org .apache .commons .lang3 .ArrayUtils ;
39+ import org .apache .commons .lang3 .ClassUtils ;
3940import org .apache .commons .lang3 .StringUtils ;
41+ import org .apache .commons .lang3 .reflect .FieldUtils ;
4042import org .apache .commons .vfs2 .impl .DefaultFileReplicator ;
4143import org .apache .commons .vfs2 .impl .DefaultFileSystemManager ;
4244import org .apache .commons .vfs2 .impl .PrivilegedFileReplicator ;
@@ -171,15 +173,23 @@ private String dumpThreadSnapshot(final Thread[] threadSnapshot) {
171173 final StringBuilder sb = new StringBuilder (256 );
172174 sb .append ("Threads still running (" + threadSnapshot .length + ") at " + Instant .now () + ", live threads:" );
173175 sb .append (System .lineSeparator ());
174-
175176 Field threadTargetField = null ;
176177 try {
177- threadTargetField = Thread .class .getDeclaredField ("target" );
178- threadTargetField .setAccessible (true );
178+ threadTargetField = FieldUtils .getDeclaredField (Thread .class , "target" , true );
179+ if (threadTargetField == null ) {
180+ // Java 21 and up
181+ threadTargetField = FieldUtils .getDeclaredField (Thread .class , "holder" , true );
182+ if (threadTargetField == null ) {
183+ System .err .println ("Test suite cannot show you a thread snapshot (Thread.holder)" );
184+ }
185+ threadTargetField = FieldUtils .getDeclaredField (threadTargetField .getClass (), "task" , true );
186+ if (threadTargetField == null ) {
187+ System .err .println ("Test suite cannot show you a thread snapshot (Thread.holder.task)" );
188+ }
189+ }
179190 } catch (final Exception e ) {
180191 System .err .println ("Test suite cannot show you a thread snapshot: " + e );
181192 }
182-
183193 int liveCount = 0 ;
184194 for (int index = 0 ; index < threadSnapshot .length ; index ++) {
185195 final Thread thread = threadSnapshot [index ];
@@ -200,7 +210,6 @@ private String dumpThreadSnapshot(final Thread[] threadSnapshot) {
200210 sb .append ("non_" );
201211 }
202212 sb .append ("daemon" );
203-
204213 if (threadTargetField != null ) {
205214 sb .append (",\t " );
206215 try {
@@ -216,7 +225,6 @@ private String dumpThreadSnapshot(final Thread[] threadSnapshot) {
216225 sb .append (")" );
217226 }
218227 }
219-
220228 sb .append (System .lineSeparator ());
221229// Stream.of(thread.getStackTrace()).forEach(e -> {
222230// sb.append('\t');
0 commit comments