Skip to content

Commit 447d311

Browse files
authored
use reflection to get thread ID (#4764)
fixes #4312
1 parent 404e6a2 commit 447d311

File tree

5 files changed

+123
-7
lines changed

5 files changed

+123
-7
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/OpenGrokThreadFactory.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818
*/
1919

2020
/*
21-
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
21+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
2222
*/
2323
package org.opengrok.indexer.configuration;
2424

2525
import org.jetbrains.annotations.NotNull;
26+
import org.opengrok.indexer.util.ThreadUtil;
2627

2728
import java.util.concurrent.Executors;
2829
import java.util.concurrent.ThreadFactory;
@@ -47,7 +48,7 @@ public OpenGrokThreadFactory(String name) {
4748
@Override
4849
public Thread newThread(@NotNull Runnable runnable) {
4950
Thread thread = Executors.defaultThreadFactory().newThread(Objects.requireNonNull(runnable, "runnable"));
50-
thread.setName(PREFIX + threadPrefix + thread.getId());
51+
thread.setName(PREFIX + threadPrefix + ThreadUtil.getThreadId(thread));
5152
return thread;
5253
}
5354
}

opengrok-indexer/src/main/java/org/opengrok/indexer/util/Executor.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919

2020
/*
21-
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
21+
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
2222
* Portions Copyright (c) 2019, Chris Fraire <[email protected]>.
2323
*/
2424
package org.opengrok.indexer.util;
@@ -412,7 +412,7 @@ public static void registerErrorHandler() {
412412
LOGGER.log(Level.FINE, "Installing default uncaught exception handler");
413413
Thread.setDefaultUncaughtExceptionHandler((t, e) ->
414414
LOGGER.log(Level.SEVERE, String.format("Uncaught exception in thread %s with ID %d: %s",
415-
t.getName(), t.getId(), e.getMessage()), e));
415+
t.getName(), ThreadUtil.getThreadId(t), e.getMessage()), e));
416416
}
417417
}
418418

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* CDDL HEADER START
3+
*
4+
* The contents of this file are subject to the terms of the
5+
* Common Development and Distribution License (the "License").
6+
* You may not use this file except in compliance with the License.
7+
*
8+
* See LICENSE.txt included in this distribution for the specific
9+
* language governing permissions and limitations under the License.
10+
*
11+
* When distributing Covered Code, include this CDDL HEADER in each
12+
* file and include the License file at LICENSE.txt.
13+
* If applicable, add the following below this CDDL HEADER, with the
14+
* fields enclosed by brackets "[]" replaced with your own identifying
15+
* information: Portions Copyright [yyyy] [name of copyright owner]
16+
*
17+
* CDDL HEADER END
18+
*/
19+
20+
/*
21+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
22+
*/
23+
package org.opengrok.indexer.util;
24+
25+
import java.lang.reflect.InvocationTargetException;
26+
import java.lang.reflect.Method;
27+
28+
public class ThreadUtil {
29+
private ThreadUtil() {
30+
// private to enforce static
31+
}
32+
33+
/**
34+
* Retrieve thread ID, preferring the non-deprecated <code>threadId</code> method.
35+
* This can be replaced with direct call after target Java version is switched to Java 21 or higher.
36+
* @param thread thread object
37+
* @return thread id
38+
*/
39+
public static long getThreadId(Thread thread) {
40+
Class<? extends Thread> clazz = thread.getClass();
41+
Method method;
42+
try {
43+
method = clazz.getMethod("threadId");
44+
} catch (NoSuchMethodException e) {
45+
try {
46+
method = clazz.getMethod("getId");
47+
} catch (NoSuchMethodException ex) {
48+
throw new RuntimeException(ex);
49+
}
50+
}
51+
try {
52+
return (long) method.invoke(thread);
53+
} catch (IllegalAccessException | InvocationTargetException e) {
54+
throw new RuntimeException(e);
55+
}
56+
}
57+
}

suggester/src/main/java/org/opengrok/suggest/Suggester.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919

2020
/*
21-
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
21+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
2222
*/
2323
package org.opengrok.suggest;
2424

@@ -34,6 +34,7 @@
3434
import org.apache.lucene.util.BytesRef;
3535
import org.jetbrains.annotations.Nullable;
3636
import org.jetbrains.annotations.VisibleForTesting;
37+
import org.opengrok.suggest.util.ThreadUtil;
3738
import org.opengrok.suggest.query.SuggesterPrefixQuery;
3839
import org.opengrok.suggest.query.SuggesterQuery;
3940
import org.opengrok.suggest.util.Progress;
@@ -161,15 +162,15 @@ public Suggester(
161162
runnable -> {
162163
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
163164
// This should match the naming in OpenGrokThreadFactory class.
164-
thread.setName("OpenGrok-suggester-lookup-" + thread.getId());
165+
thread.setName("OpenGrok-suggester-lookup-" + ThreadUtil.getThreadId(thread));
165166
return thread;
166167
});
167168

168169
this.initRebuildExecutor = Executors.newFixedThreadPool(rebuildParallelismLevel,
169170
runnable -> {
170171
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
171172
// This should match the naming in OpenGrokThreadFactory class.
172-
thread.setName("OpenGrok-suggester-rebuild-" + thread.getId());
173+
thread.setName("OpenGrok-suggester-rebuild-" + ThreadUtil.getThreadId(thread));
173174
return thread;
174175
});
175176

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* CDDL HEADER START
3+
*
4+
* The contents of this file are subject to the terms of the
5+
* Common Development and Distribution License (the "License").
6+
* You may not use this file except in compliance with the License.
7+
*
8+
* See LICENSE.txt included in this distribution for the specific
9+
* language governing permissions and limitations under the License.
10+
*
11+
* When distributing Covered Code, include this CDDL HEADER in each
12+
* file and include the License file at LICENSE.txt.
13+
* If applicable, add the following below this CDDL HEADER, with the
14+
* fields enclosed by brackets "[]" replaced with your own identifying
15+
* information: Portions Copyright [yyyy] [name of copyright owner]
16+
*
17+
* CDDL HEADER END
18+
*/
19+
20+
/*
21+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
22+
*/
23+
package org.opengrok.suggest.util;
24+
25+
import java.lang.reflect.InvocationTargetException;
26+
import java.lang.reflect.Method;
27+
28+
public class ThreadUtil {
29+
private ThreadUtil() {
30+
// private to enforce static
31+
}
32+
33+
/**
34+
* Retrieve thread ID, preferring the non-deprecated <code>threadId</code> method.
35+
* This can be replaced with direct call after target Java version is switched to Java 21 or higher.
36+
* @param thread thread object
37+
* @return thread id
38+
*/
39+
public static long getThreadId(Thread thread) {
40+
Class<? extends Thread> clazz = thread.getClass();
41+
Method method;
42+
try {
43+
method = clazz.getMethod("threadId");
44+
} catch (NoSuchMethodException e) {
45+
try {
46+
method = clazz.getMethod("getId");
47+
} catch (NoSuchMethodException ex) {
48+
throw new RuntimeException(ex);
49+
}
50+
}
51+
try {
52+
return (long) method.invoke(thread);
53+
} catch (IllegalAccessException | InvocationTargetException e) {
54+
throw new RuntimeException(e);
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)