Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions org.eclipse.jdt.debug.ui/plugin.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
###############################################################################
# Copyright (c) 2000, 2025 IBM Corporation and others.
# Copyright (c) 2000, 2026 IBM Corporation and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -267,6 +267,9 @@ javaLikeExtensions.description=Regular expression matching registered Java-like
Context.javaDebugging.name= Debugging Java
Context.javaDebugging.description= Debugging Java programs

Context.javaConsoleScope.name= In Java Stack Trace Console
Context.javaConsoleScope.description= Editing Java stack traces

newWizardCategoryName=Java Run/Debug
NewJavaScrapbookPage.label= Scrapbook Page
NewJavaScrapbookPage.description=Create a Java scrapbook page file
Expand Down Expand Up @@ -353,4 +356,7 @@ ToggleHitpointAction.label=Toggle Breakpoint with Hit Count
ToggleHitpointCommand.description=Creates or removes a breakpoint with hit count

CompareVariableClipboard.label=Compare With Clipboard
CompareVariableClipboard.tooltip=Compare Variable's Value with Clipboard Content
CompareVariableClipboard.tooltip=Compare Variable's Value with Clipboard Content

CompareExpressionClipboard.label=Compare With Clipboard
CompareExpressionClipboard.tooltip=Compare Expressions's Value with Clipboard Content
29 changes: 28 additions & 1 deletion org.eclipse.jdt.debug.ui/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<!--
Copyright (c) 2005, 2025 IBM Corporation and others.
Copyright (c) 2005, 2026 IBM Corporation and others.

This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -1588,6 +1588,19 @@
</and>
</visibility>
</objectContribution>
<objectContribution
objectClass="org.eclipse.debug.core.model.IExpression"
id="org.eclipse.debug.WatchExpressionActions.Compare">
<action
label="%CompareExpressionClipboard.label"
helpContextId="compare_expressions_clipboard_id"
class="org.eclipse.jdt.internal.debug.ui.actions.CompareObjectWithClipboard"
tooltip="%CompareExpressionClipboard.tooltip"
menubarPath="additions"
enablesFor="1"
id="org.eclipse.debug.ui.watchExpressionActions.CompareWithClipboard">
</action>
</objectContribution>
<objectContribution
id="org.eclipse.jdt.debug.ui.FilteredJavaVariableActions"
objectClass="org.eclipse.jdt.debug.core.IJavaVariable">
Expand Down Expand Up @@ -3382,6 +3395,20 @@ M4 = Platform-specific fourth key
id="org.eclipse.jdt.debug.ui.debugging"
parentId="org.eclipse.debug.ui.debugging">
</context>
<context
name="%Context.javaConsoleScope.name"
description="%Context.javaConsoleScope.description"
id="org.eclipse.jdt.debug.ui.javaConsoleScope"
parentId="org.eclipse.ui.contexts.window">
</context>
</extension>
<extension
point="org.eclipse.ui.bindings">
<key
sequence="M1+M2+F"
contextId="org.eclipse.jdt.debug.ui.javaConsoleScope"
commandId="org.eclipse.jdt.ui.edit.text.java.format"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
</extension>
<extension
point="org.eclipse.debug.ui.debugModelContextBindings">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.DebugUITools;
Expand All @@ -37,8 +40,10 @@
import org.eclipse.jdt.internal.debug.core.model.JDINullValue;
import org.eclipse.jdt.internal.debug.core.model.JDIPrimitiveValue;
import org.eclipse.jdt.internal.debug.core.model.JDIStackFrame;
import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
Expand All @@ -53,41 +58,96 @@ public void run(IAction action) {
if (selection == null) {
return;
}

Object clpbrd = getClipboard();
if (clpbrd == null) {
MessageDialog.openWarning(DebugUIPlugin.getShell(), "Comparison Failed", "Invalid clipboard content"); //$NON-NLS-1$ //$NON-NLS-2$
return;
}

if (selection.getFirstElement() instanceof IJavaVariable variable) {
try {
Object clpbrd = getClipboard();
if (clpbrd != null) {
String cb = clpbrd.toString();
String variableName = variable.getName();
if (variable.getValue() instanceof IJavaObject javaObject && !(javaObject instanceof JDINullValue)) {
if (javaObject.getJavaType() instanceof IJavaArrayType) {
StringBuilder arrBuilder = new StringBuilder("["); //$NON-NLS-1$
for (IVariable variableTemp : variable.getValue().getVariables()) {
arrBuilder.append(variableTemp.getValue() + ", "); //$NON-NLS-1$
}
arrBuilder.delete(arrBuilder.length() - 2, arrBuilder.length());
arrBuilder.append("]"); //$NON-NLS-1$
compareVariable(arrBuilder.toString(), variableName, cb);
return;
}
JDIStackFrame frame = (JDIStackFrame) DebugUITools.getDebugContext();
IJavaThread thread = (IJavaThread) frame.getThread();
IJavaValue stringVal = javaObject.sendMessage("toString", "()Ljava/lang/String;", null, thread, false); //$NON-NLS-1$//$NON-NLS-2$
String variableValue = stringVal.getValueString();
compareVariable(variableValue, variableName, cb);
}
if (variable.getValue() instanceof JDIPrimitiveValue javaPrimitive) {
compareVariable(javaPrimitive.toString(), variableName, cb);
}
} else {
MessageDialog.openWarning(DebugUIPlugin.getShell(), "Variable Value Comparision", "Invalid clipboard content"); //$NON-NLS-1$ //$NON-NLS-2$
handleCompareForValue(variable.getName(), clpbrd.toString(), variable.getValue());
return;
} catch (DebugException e) {
DebugUIPlugin.log(e);
}
}

if (selection.getFirstElement() instanceof IExpression expression) {
try {
String cb = clpbrd.toString();
String title = "Selected Expression"; //$NON-NLS-1$
if (expression instanceof JavaInspectExpression) {
handleCompareForValue(title, cb, expression.getValue());
return;
}
IValue expValue = expression.getValue();
if (expValue != null) {
compareVariable(expValue.getValueString(), title, cb);
}
} catch (DebugException e) {
DebugUIPlugin.log(e);
}
}
}

/**
* Resolves the string representation of <code>value</code> and opens the compare editor.
*
* @param title
* label for the left side of the compare editor
* @param clipboard
* active clipboard content to compare against
* @param value
* value of the selected variable or expression
* @throws DebugException
* if evaluating the value or retrieving array elements fails
*/
private void handleCompareForValue(String title, String clipboard, IValue value) throws DebugException {

if (value instanceof IJavaObject javaObject && !(javaObject instanceof JDINullValue)) {
if (javaObject.getJavaType() instanceof IJavaArrayType) {
handleCompareForArrayTypes(title, clipboard, value.getVariables());
return;
}
if (!(DebugUITools.getDebugContext() instanceof JDIStackFrame frame)) {
return;
}
IJavaThread thread = (IJavaThread) frame.getThread();
IJavaValue stringVal = javaObject.sendMessage("toString", "()Ljava/lang/String;", null, thread, false); //$NON-NLS-1$//$NON-NLS-2$
compareVariable(stringVal.getValueString(), title, clipboard);
} else if (value instanceof JDIPrimitiveValue javaPrimitive) {
compareVariable(javaPrimitive.getValueString(), title, clipboard);
}
}

/**
* Builds a string representation of the given array variables and opens the compare editor.
*
* @param title
* Label shown on the left side of the compare editor (variable name or expression text)
* @param clipboard
* Active clipboard content to compare against
* @param variables
* The array elements as <code>IVariable[]</code>, obtained from the array value
* @throws DebugException
* if retrieving a variable's value fails
*/
private void handleCompareForArrayTypes(String title, String clipboard, IVariable[] variables) throws DebugException {
if (variables.length == 0) {
compareVariable("[]", title, clipboard); //$NON-NLS-1$
return;
}
StringBuilder arrBuilder = new StringBuilder("["); //$NON-NLS-1$
for (IVariable variableTemp : variables) {
arrBuilder.append(variableTemp.getValue() + ", "); //$NON-NLS-1$
}
arrBuilder.delete(arrBuilder.length() - 2, arrBuilder.length());
arrBuilder.append("]"); //$NON-NLS-1$
compareVariable(arrBuilder.toString(), title, clipboard);
}

/**
* Creates comparable objects
*
Expand Down Expand Up @@ -136,7 +196,7 @@ public InputStream getContents() {
config.setLeftLabel(variableName);
config.setRightLabel("Contents in clipboard"); //$NON-NLS-1$
config.setLeftEditable(false);
config.setLeftEditable(false);
config.setRightEditable(false);
CompareEditorInput compareInput = new CompareEditorInput(config) {
@Override
protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
Expand All @@ -163,4 +223,24 @@ private Object getClipboard() {
}
}

@Override
public void selectionChanged(IAction action, ISelection selection) {
if (selection instanceof IStructuredSelection ss) {
if (ss.getFirstElement() instanceof IExpression expression) {
if (expression.getValue() == null) {
action.setEnabled(false);
return;
}
IDebugTarget target = expression.getDebugTarget();
if (target == null) {
action.setEnabled(false);
return;
}
if (target.isTerminated() || target.isDisconnected()) {
action.setEnabled(false);
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
*/
public class JavaStackTracePageParticipant implements IConsolePageParticipant {

/**
* Dedicated context activated while a Java stack trace console page is showing, used only to enable the Format command's key binding (see
* jdt.debug.ui's plugin.xml). This is intentionally <b>not</b> the shared "org.eclipse.jdt.ui.javaEditorScope"/"org.eclipse.ui.textEditorScope"
* context: activating those would also make unrelated generic text/java editor key bindings (e.g. the zoom in/out commands) take priority over
* this console's own key bindings while it is showing.
*/
private static final String JAVA_CONSOLE_SCOPE = "org.eclipse.jdt.debug.ui.javaConsoleScope"; //$NON-NLS-1$

private CloseConsoleAction fCloseAction;
private FormatStackTraceActionDelegate fFormatAction;
private IHandlerActivation fHandlerActivation;
Expand Down Expand Up @@ -88,8 +96,13 @@ public Object execute(ExecutionEvent event) throws ExecutionException {

fHandlerActivation = handlerService.activateHandler("org.eclipse.jdt.ui.edit.text.java.format", formatHandler); //$NON-NLS-1$

// Activate our own dedicated context (rather than the shared java/text
// editor scope) so that the Format command's Ctrl+Shift+F key binding
// works here, without dragging in unrelated generic editor key bindings
// (e.g. zoom in/out) that would otherwise take priority over this
// console's own key bindings while it is showing.
IContextService contextService = workbench.getAdapter(IContextService.class);
fContextActivation = contextService.activateContext("org.eclipse.jdt.ui.javaEditorScope"); //$NON-NLS-1$
fContextActivation = contextService.activateContext(JAVA_CONSOLE_SCOPE);
}

/* (non-Javadoc)
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.jdt.debug/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.debug; singleton:=true
Bundle-Version: 3.26.0.qualifier
Bundle-Version: 3.26.100.qualifier
Bundle-ClassPath: jdimodel.jar
Bundle-Activator: org.eclipse.jdt.internal.debug.core.JDIDebugPlugin
Bundle-Vendor: %providerName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ public class JDIThread extends JDIDebugElement implements IJavaThread {
*/
private static final String MAIN_THREAD_GROUP = "main"; //$NON-NLS-1$

/**
* Constant for the name of the {@code RMI Runtime} thread group. See internal JDK method {@code sun.rmi.runtime.RuntimeUtil.newUserThread()},
* which uses: {@code sun.rmi.runtime.RuntimeUtil.userThreadGroup}
*/
private static final String RMI_RUNTIME_THREAD_GROUP = "RMI Runtime"; //$NON-NLS-1$

/**
* @since 3.5
*/
Expand Down Expand Up @@ -565,7 +571,7 @@ protected void determineIfSystemThread() throws DebugException {
// #targetRequestFailed will throw an exception
return;
}
if (tgn != null && tgn.equals(MAIN_THREAD_GROUP)) {
if (MAIN_THREAD_GROUP.equals(tgn) || RMI_RUNTIME_THREAD_GROUP.equals(tgn)) {
fIsSystemThread = false;
break;
}
Expand Down
Loading