From 65f71a50b449668a805f0e361e6b73076654ff87 Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Thu, 17 Apr 2025 11:07:23 +0200 Subject: [PATCH 1/2] use reflection to get thread ID fixes #4312 --- .../configuration/OpenGrokThreadFactory.java | 5 +- .../org/opengrok/indexer/util/Executor.java | 4 +- .../org/opengrok/indexer/util/ThreadUtil.java | 55 +++++++++++++++++++ .../java/org/opengrok/suggest/Suggester.java | 7 ++- .../org/opengrok/suggest/util/ThreadUtil.java | 55 +++++++++++++++++++ 5 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 opengrok-indexer/src/main/java/org/opengrok/indexer/util/ThreadUtil.java create mode 100644 suggester/src/main/java/org/opengrok/suggest/util/ThreadUtil.java diff --git a/opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/OpenGrokThreadFactory.java b/opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/OpenGrokThreadFactory.java index c8e5f318381..32cfbca52ac 100644 --- a/opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/OpenGrokThreadFactory.java +++ b/opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/OpenGrokThreadFactory.java @@ -18,11 +18,12 @@ */ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. */ package org.opengrok.indexer.configuration; import org.jetbrains.annotations.NotNull; +import org.opengrok.indexer.util.ThreadUtil; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; @@ -47,7 +48,7 @@ public OpenGrokThreadFactory(String name) { @Override public Thread newThread(@NotNull Runnable runnable) { Thread thread = Executors.defaultThreadFactory().newThread(Objects.requireNonNull(runnable, "runnable")); - thread.setName(PREFIX + threadPrefix + thread.getId()); + thread.setName(PREFIX + threadPrefix + ThreadUtil.getThreadId(thread)); return thread; } } diff --git a/opengrok-indexer/src/main/java/org/opengrok/indexer/util/Executor.java b/opengrok-indexer/src/main/java/org/opengrok/indexer/util/Executor.java index 773c1ecc18d..3550f5956e7 100644 --- a/opengrok-indexer/src/main/java/org/opengrok/indexer/util/Executor.java +++ b/opengrok-indexer/src/main/java/org/opengrok/indexer/util/Executor.java @@ -18,7 +18,7 @@ */ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * Portions Copyright (c) 2019, Chris Fraire . */ package org.opengrok.indexer.util; @@ -412,7 +412,7 @@ public static void registerErrorHandler() { LOGGER.log(Level.FINE, "Installing default uncaught exception handler"); Thread.setDefaultUncaughtExceptionHandler((t, e) -> LOGGER.log(Level.SEVERE, String.format("Uncaught exception in thread %s with ID %d: %s", - t.getName(), t.getId(), e.getMessage()), e)); + t.getName(), ThreadUtil.getThreadId(t), e.getMessage()), e)); } } diff --git a/opengrok-indexer/src/main/java/org/opengrok/indexer/util/ThreadUtil.java b/opengrok-indexer/src/main/java/org/opengrok/indexer/util/ThreadUtil.java new file mode 100644 index 00000000000..6818111276d --- /dev/null +++ b/opengrok-indexer/src/main/java/org/opengrok/indexer/util/ThreadUtil.java @@ -0,0 +1,55 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * See LICENSE.txt included in this distribution for the specific + * language governing permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at LICENSE.txt. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + */ +package org.opengrok.indexer.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class ThreadUtil { + private ThreadUtil() { + // private to enforce static + } + + /** + * @param thread thread object + * @return thread id + */ + public static long getThreadId(Thread thread) { + Class clazz = thread.getClass(); + Method method; + try { + method = clazz.getMethod("threadId"); + } catch (NoSuchMethodException e) { + try { + method = clazz.getMethod("getId"); + } catch (NoSuchMethodException ex) { + throw new RuntimeException(ex); + } + } + try { + return (long) method.invoke(thread); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } +} diff --git a/suggester/src/main/java/org/opengrok/suggest/Suggester.java b/suggester/src/main/java/org/opengrok/suggest/Suggester.java index 6f7073e4160..28b7f890e41 100644 --- a/suggester/src/main/java/org/opengrok/suggest/Suggester.java +++ b/suggester/src/main/java/org/opengrok/suggest/Suggester.java @@ -18,7 +18,7 @@ */ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. */ package org.opengrok.suggest; @@ -34,6 +34,7 @@ import org.apache.lucene.util.BytesRef; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.VisibleForTesting; +import org.opengrok.suggest.util.ThreadUtil; import org.opengrok.suggest.query.SuggesterPrefixQuery; import org.opengrok.suggest.query.SuggesterQuery; import org.opengrok.suggest.util.Progress; @@ -161,7 +162,7 @@ public Suggester( runnable -> { Thread thread = Executors.defaultThreadFactory().newThread(runnable); // This should match the naming in OpenGrokThreadFactory class. - thread.setName("OpenGrok-suggester-lookup-" + thread.getId()); + thread.setName("OpenGrok-suggester-lookup-" + ThreadUtil.getThreadId(thread)); return thread; }); @@ -169,7 +170,7 @@ public Suggester( runnable -> { Thread thread = Executors.defaultThreadFactory().newThread(runnable); // This should match the naming in OpenGrokThreadFactory class. - thread.setName("OpenGrok-suggester-rebuild-" + thread.getId()); + thread.setName("OpenGrok-suggester-rebuild-" + ThreadUtil.getThreadId(thread)); return thread; }); diff --git a/suggester/src/main/java/org/opengrok/suggest/util/ThreadUtil.java b/suggester/src/main/java/org/opengrok/suggest/util/ThreadUtil.java new file mode 100644 index 00000000000..b2aee0d019d --- /dev/null +++ b/suggester/src/main/java/org/opengrok/suggest/util/ThreadUtil.java @@ -0,0 +1,55 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * See LICENSE.txt included in this distribution for the specific + * language governing permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at LICENSE.txt. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + */ +package org.opengrok.suggest.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class ThreadUtil { + private ThreadUtil() { + // private to enforce static + } + + /** + * @param thread thread object + * @return thread id + */ + public static long getThreadId(Thread thread) { + Class clazz = thread.getClass(); + Method method; + try { + method = clazz.getMethod("threadId"); + } catch (NoSuchMethodException e) { + try { + method = clazz.getMethod("getId"); + } catch (NoSuchMethodException ex) { + throw new RuntimeException(ex); + } + } + try { + return (long) method.invoke(thread); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } +} From 879ba0fdb100948b399070fd2acf372d8d69ad9b Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Thu, 17 Apr 2025 11:19:48 +0200 Subject: [PATCH 2/2] add comment --- .../src/main/java/org/opengrok/indexer/util/ThreadUtil.java | 2 ++ .../src/main/java/org/opengrok/suggest/util/ThreadUtil.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/opengrok-indexer/src/main/java/org/opengrok/indexer/util/ThreadUtil.java b/opengrok-indexer/src/main/java/org/opengrok/indexer/util/ThreadUtil.java index 6818111276d..2ed675f2b33 100644 --- a/opengrok-indexer/src/main/java/org/opengrok/indexer/util/ThreadUtil.java +++ b/opengrok-indexer/src/main/java/org/opengrok/indexer/util/ThreadUtil.java @@ -31,6 +31,8 @@ private ThreadUtil() { } /** + * Retrieve thread ID, preferring the non-deprecated threadId method. + * This can be replaced with direct call after target Java version is switched to Java 21 or higher. * @param thread thread object * @return thread id */ diff --git a/suggester/src/main/java/org/opengrok/suggest/util/ThreadUtil.java b/suggester/src/main/java/org/opengrok/suggest/util/ThreadUtil.java index b2aee0d019d..03fe20d7bdf 100644 --- a/suggester/src/main/java/org/opengrok/suggest/util/ThreadUtil.java +++ b/suggester/src/main/java/org/opengrok/suggest/util/ThreadUtil.java @@ -31,6 +31,8 @@ private ThreadUtil() { } /** + * Retrieve thread ID, preferring the non-deprecated threadId method. + * This can be replaced with direct call after target Java version is switched to Java 21 or higher. * @param thread thread object * @return thread id */