diff --git a/.idea/modules.xml b/.idea/modules.xml
index f532749a71e6..8b50d33e321e 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -789,6 +789,7 @@
+
diff --git a/java/debugger/impl/intellij.java.debugger.impl.iml b/java/debugger/impl/intellij.java.debugger.impl.iml
index d5c0275f1c3f..254f1474bd61 100644
--- a/java/debugger/impl/intellij.java.debugger.impl.iml
+++ b/java/debugger/impl/intellij.java.debugger.impl.iml
@@ -79,6 +79,7 @@
+
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ExportThreadsAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ExportThreadsAction.java
index dc461d627f52..dba88648de7e 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ExportThreadsAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/ExportThreadsAction.java
@@ -16,7 +16,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.unscramble.ThreadDumpPanel;
-import com.intellij.unscramble.ThreadState;
+import com.intellij.threadDumpParser.ThreadState;
import org.jetbrains.annotations.NotNull;
import java.util.List;
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java
index 306a5bcbadd5..7575c64c6f8f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java
@@ -17,8 +17,8 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
-import com.intellij.unscramble.ThreadDumpParser;
-import com.intellij.unscramble.ThreadState;
+import com.intellij.threadDumpParser.ThreadDumpParser;
+import com.intellij.threadDumpParser.ThreadState;
import com.intellij.util.SmartList;
import com.intellij.xdebugger.XDebugSession;
import com.sun.jdi.*;
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java
index fcfaad5f2808..3c839068321f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java
@@ -45,7 +45,7 @@ import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.ui.content.Content;
import com.intellij.ui.viewModel.extraction.ToolWindowContentExtractor;
import com.intellij.unscramble.ThreadDumpPanel;
-import com.intellij.unscramble.ThreadState;
+import com.intellij.threadDumpParser.ThreadState;
import com.intellij.util.DocumentUtil;
import com.intellij.util.SmartList;
import com.intellij.util.ThreeState;
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java b/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java
index 43c2ac6ee047..de803d127fba 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java
@@ -15,7 +15,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
-import com.intellij.unscramble.ThreadState;
+import com.intellij.threadDumpParser.ThreadState;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.MessageCategory;
import com.intellij.xdebugger.XDebugSession;
diff --git a/java/execution/impl/intellij.java.execution.impl.iml b/java/execution/impl/intellij.java.execution.impl.iml
index 80da0c0f8ac8..20786f97e650 100644
--- a/java/execution/impl/intellij.java.execution.impl.iml
+++ b/java/execution/impl/intellij.java.execution.impl.iml
@@ -43,6 +43,7 @@
+
diff --git a/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java b/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
index a93bc16949b4..9d39146062fd 100644
--- a/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
+++ b/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
@@ -36,8 +36,8 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.unscramble.AnalyzeStacktraceUtil;
import com.intellij.unscramble.ThreadDumpConsoleFactory;
-import com.intellij.unscramble.ThreadDumpParser;
-import com.intellij.unscramble.ThreadState;
+import com.intellij.threadDumpParser.ThreadDumpParser;
+import com.intellij.threadDumpParser.ThreadState;
import com.intellij.util.ArrayUtil;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.concurrency.AppExecutorUtil;
diff --git a/java/java-impl/intellij.java.impl.iml b/java/java-impl/intellij.java.impl.iml
index 33d39be627e2..d6bec7a7e296 100644
--- a/java/java-impl/intellij.java.impl.iml
+++ b/java/java-impl/intellij.java.impl.iml
@@ -80,6 +80,7 @@
+
diff --git a/java/java-impl/src/com/intellij/unscramble/ThreadDumpConsoleFactory.java b/java/java-impl/src/com/intellij/unscramble/ThreadDumpConsoleFactory.java
index efa7b49cc1c4..2ab9036e4269 100644
--- a/java/java-impl/src/com/intellij/unscramble/ThreadDumpConsoleFactory.java
+++ b/java/java-impl/src/com/intellij/unscramble/ThreadDumpConsoleFactory.java
@@ -18,6 +18,7 @@ package com.intellij.unscramble;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.project.Project;
+import com.intellij.threadDumpParser.ThreadState;
import javax.swing.*;
import java.util.List;
diff --git a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java
index 6d4cae9e9aca..a2dd2276ad43 100644
--- a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java
+++ b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java
@@ -26,6 +26,8 @@ import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.threadDumpParser.ThreadOperation;
+import com.intellij.threadDumpParser.ThreadState;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.util.PlatformIcons;
diff --git a/java/unscramble/intellij.java.unscramble.iml b/java/unscramble/intellij.java.unscramble.iml
index 96c99b1b9223..afbfa244a001 100644
--- a/java/unscramble/intellij.java.unscramble.iml
+++ b/java/unscramble/intellij.java.unscramble.iml
@@ -16,5 +16,6 @@
+
\ No newline at end of file
diff --git a/java/unscramble/src/com/intellij/unscramble/UnscrambleDialog.java b/java/unscramble/src/com/intellij/unscramble/UnscrambleDialog.java
index d57b513e33de..ef2bb37e7e12 100644
--- a/java/unscramble/src/com/intellij/unscramble/UnscrambleDialog.java
+++ b/java/unscramble/src/com/intellij/unscramble/UnscrambleDialog.java
@@ -20,6 +20,8 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.configurable.VcsContentAnnotationConfigurable;
+import com.intellij.threadDumpParser.ThreadDumpParser;
+import com.intellij.threadDumpParser.ThreadState;
import com.intellij.ui.GuiUtils;
import com.intellij.ui.SimpleListCellRenderer;
import com.intellij.ui.TextFieldWithHistory;
@@ -45,7 +47,6 @@ public class UnscrambleDialog extends DialogWrapper {
private static final @NonNls String PROPERTY_LOG_FILE_LAST_URL = "UNSCRAMBLE_LOG_FILE_LAST_URL";
private static final @NonNls String PROPERTY_UNSCRAMBLER_NAME_USED = "UNSCRAMBLER_NAME_USED";
private static final Condition DEADLOCK_CONDITION = state -> state.isDeadlocked();
- private static final String[] IMPORTANT_THREAD_DUMP_WORDS = ContainerUtil.ar("tid", "nid", "wait", "parking", "prio", "os_prio", "java");
private final Project myProject;
private JPanel myEditorPanel;
@@ -279,77 +280,10 @@ public class UnscrambleDialog extends DialogWrapper {
@Override
public void actionPerformed(ActionEvent e){
String text = myStacktraceEditorPanel.getText();
- myStacktraceEditorPanel.setText(normalizeText(text));
+ myStacktraceEditorPanel.setText(ThreadDumpParser.normalizeText(text));
}
}
- public static String normalizeText(@NonNls String text) {
- StringBuilder builder = new StringBuilder(text.length());
-
- text = text.replaceAll("(\\S[ \\t\\x0B\\f\\r]+)(at\\s+)", "$1\n$2");
- text = text.replaceAll("(\\\\n|\\\\r|\\\\t)+(at\\s+)", "\n$2");
- String[] lines = text.split("\n");
-
- boolean first = true;
- boolean inAuxInfo = false;
- for (final String line : lines) {
- //noinspection HardCodedStringLiteral
- if (!inAuxInfo && (line.startsWith("JNI global references") || line.trim().equals("Heap"))) {
- builder.append("\n");
- inAuxInfo = true;
- }
- if (inAuxInfo) {
- builder.append(trimSuffix(line)).append("\n");
- continue;
- }
- if (line.startsWith("at breakpoint")) { // possible thread status mixed with "at ..."
- builder.append(" ").append(trimSuffix(line));
- continue;
- }
- if (!first && (mustHaveNewLineBefore(line) || StringUtil.endsWith(builder, ")"))) {
- if (!StringUtil.endsWith(builder, "\n")) builder.append("\n");
- if (line.startsWith("\"")) builder.append("\n"); // Additional line break for thread names
- }
- first = false;
- int i = builder.lastIndexOf("\n");
- CharSequence lastLine = i == -1 ? builder : builder.subSequence(i + 1, builder.length());
- if (!line.matches("\\s+.*") && lastLine.length() > 0) {
- if (lastLine.toString().matches("\\s*at") //separate 'at' from filename
- || ContainerUtil.or(IMPORTANT_THREAD_DUMP_WORDS, word -> line.startsWith(word))) {
- builder.append(" ");
- }
- }
- builder.append(trimSuffix(line));
- }
- return builder.toString();
- }
-
- private static String trimSuffix(final String line) {
- int len = line.length();
-
- while ((0 < len) && (line.charAt(len-1) <= ' ')) {
- len--;
- }
- return (len < line.length()) ? line.substring(0, len) : line;
- }
-
- private static boolean mustHaveNewLineBefore(String line) {
- final int nonWs = CharArrayUtil.shiftForward(line, 0, " \t");
- if (nonWs < line.length()) {
- line = line.substring(nonWs);
- }
-
- if (line.startsWith("at")) return true; // Start of the new stack frame entry
- if (line.startsWith("Caused")) return true; // Caused by message
- if (line.startsWith("- locked")) return true; // "Locked a monitor" logging
- if (line.startsWith("- waiting")) return true; // "Waiting for monitor" logging
- if (line.startsWith("- parking to wait")) return true;
- if (line.startsWith("java.lang.Thread.State")) return true;
- if (line.startsWith("\"")) return true; // Start of the new thread (thread name)
-
- return false;
- }
-
@Override
protected void doOKAction() {
if (myConfigurable != null && myConfigurable.isModified()) {
diff --git a/java/unscramble/src/com/intellij/unscramble/UnscrambleListener.java b/java/unscramble/src/com/intellij/unscramble/UnscrambleListener.java
index ef9ccd2b51b5..d84253a4ecaa 100644
--- a/java/unscramble/src/com/intellij/unscramble/UnscrambleListener.java
+++ b/java/unscramble/src/com/intellij/unscramble/UnscrambleListener.java
@@ -7,6 +7,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.threadDumpParser.ThreadDumpParser;
import org.jetbrains.annotations.NotNull;
import java.util.regex.Pattern;
@@ -35,7 +36,7 @@ class UnscrambleListener extends ClipboardAnalyzeListener {
@Override
public boolean canHandle(@NotNull String value) {
- value = UnscrambleDialog.normalizeText(value);
+ value = ThreadDumpParser.normalizeText(value);
int linesCount = 0;
for (String line : value.split("\n")) {
line = line.trim();
diff --git a/platform/threadDumpParser/api-dump.txt b/platform/threadDumpParser/api-dump.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/platform/threadDumpParser/intellij.platform.threadDumpParser.iml b/platform/threadDumpParser/intellij.platform.threadDumpParser.iml
new file mode 100644
index 000000000000..a5c8ed2433ab
--- /dev/null
+++ b/platform/threadDumpParser/intellij.platform.threadDumpParser.iml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/unscramble/ThreadDumpParser.java b/platform/threadDumpParser/src/com/intellij/threadDumpParser/ThreadDumpParser.java
similarity index 77%
rename from java/java-impl/src/com/intellij/unscramble/ThreadDumpParser.java
rename to platform/threadDumpParser/src/com/intellij/threadDumpParser/ThreadDumpParser.java
index b4f437ad6cc6..9f98f3e2263b 100644
--- a/java/java-impl/src/com/intellij/unscramble/ThreadDumpParser.java
+++ b/platform/threadDumpParser/src/com/intellij/threadDumpParser/ThreadDumpParser.java
@@ -1,8 +1,11 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.unscramble;
+package com.intellij.threadDumpParser;
import com.intellij.diagnostic.EventCountDumper;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -14,7 +17,7 @@ import java.util.regex.Pattern;
import static com.intellij.diagnostic.CoroutineDumperKt.isCoroutineDumpHeader;
-
+@ApiStatus.Internal
public final class ThreadDumpParser {
private static final Pattern ourThreadStartPattern = Pattern.compile("^\"(.+)\".+(prio=\\d+ (?:os_prio=[^\\s]+ )?.*tid=[^\\s]+ nid=[^\\s]+|[Ii][Dd]=\\d+) ([^\\[]+)");
private static final Pattern ourForcedThreadStartPattern = Pattern.compile("^Thread (\\d+): \\(state = (.+)\\)");
@@ -30,6 +33,8 @@ public final class ThreadDumpParser {
private static final String AT_JAVA_LANG_OBJECT_WAIT = "at java.lang.Object.wait(";
private static final Pattern ourLockedOwnableSynchronizersPattern = Pattern.compile("- <(0x[\\da-f]+)> \\(.*\\)");
+ private static final String[] IMPORTANT_THREAD_DUMP_WORDS = ContainerUtil.ar("tid", "nid", "wait", "parking", "prio", "os_prio", "java");
+
private ThreadDumpParser() {
}
@@ -263,4 +268,72 @@ public final class ThreadDumpParser {
}
return false;
}
+
+ public static String normalizeText(@NonNls String text) {
+ StringBuilder builder = new StringBuilder(text.length());
+
+ text = text.replaceAll("(\\S[ \\t\\x0B\\f\\r]+)(at\\s+)", "$1\n$2");
+ text = text.replaceAll("(\\\\n|\\\\r|\\\\t)+(at\\s+)", "\n$2");
+ String[] lines = text.split("\n");
+
+ boolean first = true;
+ boolean inAuxInfo = false;
+ for (final String line : lines) {
+ //noinspection HardCodedStringLiteral
+ if (!inAuxInfo && (line.startsWith("JNI global references") || line.trim().equals("Heap"))) {
+ builder.append("\n");
+ inAuxInfo = true;
+ }
+ if (inAuxInfo) {
+ builder.append(trimSuffix(line)).append("\n");
+ continue;
+ }
+ if (line.startsWith("at breakpoint")) { // possible thread status mixed with "at ..."
+ builder.append(" ").append(trimSuffix(line));
+ continue;
+ }
+ if (!first && (mustHaveNewLineBefore(line) || StringUtil.endsWith(builder, ")"))) {
+ if (!StringUtil.endsWith(builder, "\n")) builder.append("\n");
+ if (line.startsWith("\"")) builder.append("\n"); // Additional line break for thread names
+ }
+ first = false;
+ int i = builder.lastIndexOf("\n");
+ CharSequence lastLine = i == -1 ? builder : builder.subSequence(i + 1, builder.length());
+ if (!line.matches("\\s+.*") && lastLine.length() > 0) {
+ if (lastLine.toString().matches("\\s*at") //separate 'at' from filename
+ || ContainerUtil.or(IMPORTANT_THREAD_DUMP_WORDS, word -> line.startsWith(word))) {
+ builder.append(" ");
+ }
+ }
+ builder.append(trimSuffix(line));
+ }
+ return builder.toString();
+ }
+
+ private static boolean mustHaveNewLineBefore(String line) {
+ final int nonWs = CharArrayUtil.shiftForward(line, 0, " \t");
+ if (nonWs < line.length()) {
+ line = line.substring(nonWs);
+ }
+
+ if (line.startsWith("at")) return true; // Start of the new stack frame entry
+ if (line.startsWith("Caused")) return true; // Caused by message
+ if (line.startsWith("- locked")) return true; // "Locked a monitor" logging
+ if (line.startsWith("- waiting")) return true; // "Waiting for monitor" logging
+ if (line.startsWith("- parking to wait")) return true;
+ if (line.startsWith("java.lang.Thread.State")) return true;
+ if (line.startsWith("\"")) return true; // Start of the new thread (thread name)
+
+ return false;
+ }
+
+ private static String trimSuffix(final String line) {
+ int len = line.length();
+
+ while ((0 < len) && (line.charAt(len - 1) <= ' ')) {
+ len--;
+ }
+ return (len < line.length()) ? line.substring(0, len) : line;
+ }
+
}
diff --git a/java/java-impl/src/com/intellij/unscramble/ThreadOperation.java b/platform/threadDumpParser/src/com/intellij/threadDumpParser/ThreadOperation.java
similarity index 77%
rename from java/java-impl/src/com/intellij/unscramble/ThreadOperation.java
rename to platform/threadDumpParser/src/com/intellij/threadDumpParser/ThreadOperation.java
index 35c7675d03ad..4079fdebb539 100644
--- a/java/java-impl/src/com/intellij/unscramble/ThreadOperation.java
+++ b/platform/threadDumpParser/src/com/intellij/threadDumpParser/ThreadOperation.java
@@ -1,7 +1,9 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
-package com.intellij.unscramble;
+package com.intellij.threadDumpParser;
+import org.jetbrains.annotations.ApiStatus;
+@ApiStatus.Internal
public enum ThreadOperation {
Socket("socket operation"), IO("I/O");
diff --git a/java/java-impl/src/com/intellij/unscramble/ThreadState.java b/platform/threadDumpParser/src/com/intellij/threadDumpParser/ThreadState.java
similarity index 98%
rename from java/java-impl/src/com/intellij/unscramble/ThreadState.java
rename to platform/threadDumpParser/src/com/intellij/threadDumpParser/ThreadState.java
index af2153af2846..cc7a8f0577de 100644
--- a/java/java-impl/src/com/intellij/unscramble/ThreadState.java
+++ b/platform/threadDumpParser/src/com/intellij/threadDumpParser/ThreadState.java
@@ -1,17 +1,18 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.unscramble;
+package com.intellij.threadDumpParser;
import com.intellij.diagnostic.ThreadDumper;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
-
+@ApiStatus.Internal
public class ThreadState {
private final String myName;
private final String myState;
diff --git a/java/java-tests/testSrc/com/intellij/unscramble/NormalizeTextTest.java b/platform/threadDumpParser/testSrc/com/intellij/threadDumpParser/NormalizeTextTest.java
similarity index 98%
rename from java/java-tests/testSrc/com/intellij/unscramble/NormalizeTextTest.java
rename to platform/threadDumpParser/testSrc/com/intellij/threadDumpParser/NormalizeTextTest.java
index 78deb81b032b..99ed57574a93 100644
--- a/java/java-tests/testSrc/com/intellij/unscramble/NormalizeTextTest.java
+++ b/platform/threadDumpParser/testSrc/com/intellij/threadDumpParser/NormalizeTextTest.java
@@ -1,5 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.unscramble;
+package com.intellij.threadDumpParser;
import junit.framework.TestCase;
import org.jetbrains.annotations.NonNls;
@@ -165,7 +165,7 @@ public class NormalizeTextTest extends TestCase {
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)""");
- assertEquals(2, ThreadDumpParser.parse(UnscrambleDialog.normalizeText(text)).size());
+ assertEquals(2, ThreadDumpParser.parse(ThreadDumpParser.normalizeText(text)).size());
}
public void testJsonEscapes() {
@@ -182,6 +182,6 @@ public class NormalizeTextTest extends TestCase {
}
private static void doTest(@NonNls String stackTrace, @NonNls String expected) {
- assertEquals(expected, UnscrambleDialog.normalizeText(stackTrace));
+ assertEquals(expected, ThreadDumpParser.normalizeText(stackTrace));
}
}
diff --git a/java/java-tests/testSrc/com/intellij/unscramble/ThreadDumpParserTest.java b/platform/threadDumpParser/testSrc/com/intellij/threadDumpParser/ThreadDumpParserTest.java
similarity index 99%
rename from java/java-tests/testSrc/com/intellij/unscramble/ThreadDumpParserTest.java
rename to platform/threadDumpParser/testSrc/com/intellij/threadDumpParser/ThreadDumpParserTest.java
index bfa19366bd69..e8ca3999e924 100644
--- a/java/java-tests/testSrc/com/intellij/unscramble/ThreadDumpParserTest.java
+++ b/platform/threadDumpParser/testSrc/com/intellij/threadDumpParser/ThreadDumpParserTest.java
@@ -1,5 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.unscramble;
+package com.intellij.threadDumpParser;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.tools.ide.metrics.benchmark.Benchmark;