Skip to content

Commit 5b538f0

Browse files
Fixed old regression in ErrorDialogWithToggle from commit 24b179
The change in commit 24b1795 reverted the logic of the "don't tell me again" toggle button and only updated JavaHotCodeReplaceListener (which opens HotCodeReplaceErrorDialog). However NoLineNumberAttributesStatusHandler also used ErrorDialogWithToggle but it wasn't updated. This commit fixes "No line attributes error" dialog on breakpoints opened by NoLineNumberAttributesStatusHandler regarding the "Don't tell me again" checkbox behavior. After commit above the value wasn't stored in the preference store. Added regression test to easily reproduce the dialog opening and checking its functionality. Fixes https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/2648
1 parent 6035422 commit 5b538f0

File tree

5 files changed

+270
-1
lines changed

5 files changed

+270
-1
lines changed

org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
import org.eclipse.jdt.debug.tests.ui.DebugHoverTests;
150150
import org.eclipse.jdt.debug.tests.ui.DebugViewTests;
151151
import org.eclipse.jdt.debug.tests.ui.DetailPaneManagerTests;
152+
import org.eclipse.jdt.debug.tests.ui.HotCodeReplaceErrorDialogTest;
152153
import org.eclipse.jdt.debug.tests.ui.JavaSnippetEditorTest;
153154
import org.eclipse.jdt.debug.tests.ui.NoLineNumberAttributesStatusHandlerTest;
154155
import org.eclipse.jdt.debug.tests.ui.OpenFromClipboardTests;
@@ -345,6 +346,9 @@ public AutomatedSuite() {
345346
// No Line Number Attributes Status Handler tests
346347
addTest(new TestSuite(NoLineNumberAttributesStatusHandlerTest.class));
347348

349+
// Test that ErrorDialogWithToggle Override functionalities won't cause a Stackoverflow Exception
350+
addTest(new TestSuite(HotCodeReplaceErrorDialogTest.class));
351+
348352
// Debug hover tests
349353
addTest(new TestSuite(DebugHoverTests.class));
350354

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Advantest Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Advantest Corporation - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.jdt.debug.tests;
15+
16+
import org.eclipse.core.resources.IMarkerDelta;
17+
import org.eclipse.debug.core.DebugException;
18+
import org.eclipse.debug.core.ILaunch;
19+
import org.eclipse.debug.core.model.IBreakpoint;
20+
import org.eclipse.debug.core.model.IDebugTarget;
21+
import org.eclipse.debug.core.model.IMemoryBlock;
22+
import org.eclipse.debug.core.model.IProcess;
23+
import org.eclipse.debug.core.model.IThread;
24+
25+
/**
26+
* This is a test debug target which can be used to mimic an IDebugTarget instance.
27+
*/
28+
public class TestDebugTarget implements IDebugTarget {
29+
30+
@Override
31+
public boolean supportsStorageRetrieval() {
32+
return false;
33+
}
34+
35+
@Override
36+
public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException {
37+
return null;
38+
}
39+
40+
@Override
41+
public boolean isDisconnected() {
42+
return false;
43+
}
44+
45+
@Override
46+
public void disconnect() throws DebugException {
47+
48+
}
49+
50+
@Override
51+
public boolean canDisconnect() {
52+
return false;
53+
}
54+
55+
@Override
56+
public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
57+
58+
}
59+
60+
@Override
61+
public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
62+
63+
}
64+
65+
@Override
66+
public void breakpointAdded(IBreakpoint breakpoint) {
67+
68+
}
69+
70+
@Override
71+
public void suspend() throws DebugException {
72+
73+
}
74+
75+
@Override
76+
public void resume() throws DebugException {
77+
78+
}
79+
80+
@Override
81+
public boolean isSuspended() {
82+
return false;
83+
}
84+
85+
@Override
86+
public boolean canSuspend() {
87+
return false;
88+
}
89+
90+
@Override
91+
public boolean canResume() {
92+
return false;
93+
}
94+
95+
@Override
96+
public void terminate() throws DebugException {
97+
98+
}
99+
100+
@Override
101+
public boolean isTerminated() {
102+
return false;
103+
}
104+
105+
@Override
106+
public boolean canTerminate() {
107+
return false;
108+
}
109+
110+
@Override
111+
public <T> T getAdapter(Class<T> adapter) {
112+
return null;
113+
}
114+
115+
@Override
116+
public String getModelIdentifier() {
117+
return null;
118+
}
119+
120+
@Override
121+
public ILaunch getLaunch() {
122+
return null;
123+
}
124+
125+
@Override
126+
public IDebugTarget getDebugTarget() {
127+
return null;
128+
}
129+
130+
@Override
131+
public boolean supportsBreakpoint(IBreakpoint breakpoint) {
132+
return false;
133+
}
134+
135+
@Override
136+
public boolean hasThreads() throws DebugException {
137+
return false;
138+
}
139+
140+
@Override
141+
public IThread[] getThreads() throws DebugException {
142+
return null;
143+
}
144+
145+
@Override
146+
public IProcess getProcess() {
147+
return null;
148+
}
149+
150+
@Override
151+
public String getName() throws DebugException {
152+
return null;
153+
}
154+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Advantest Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Advantest Corporation - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.jdt.debug.tests.ui;
15+
16+
import org.eclipse.core.runtime.IStatus;
17+
import org.eclipse.core.runtime.Status;
18+
import org.eclipse.debug.core.model.IDebugTarget;
19+
import org.eclipse.jdt.debug.tests.TestDebugTarget;
20+
import org.eclipse.jdt.internal.debug.ui.DebugUIMessages;
21+
import org.eclipse.jdt.internal.debug.ui.HotCodeReplaceErrorDialog;
22+
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
23+
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
24+
import org.eclipse.jface.dialogs.ErrorDialog;
25+
import org.eclipse.jface.dialogs.IDialogConstants;
26+
import org.eclipse.jface.preference.IPreferenceStore;
27+
import org.eclipse.osgi.util.NLS;
28+
import org.eclipse.swt.events.ShellAdapter;
29+
import org.eclipse.swt.events.ShellEvent;
30+
import org.eclipse.swt.widgets.Shell;
31+
import org.junit.Test;
32+
33+
public class HotCodeReplaceErrorDialogTest extends AbstractDebugUiTests {
34+
35+
private final class HotCodeReplaceErrorDialogSimRunnable implements Runnable {
36+
private final IStatus status;
37+
private final String toggleMessage;
38+
private final String prefAlertObsoleteMethods;
39+
private final String toggleMessage2;
40+
private final IPreferenceStore preferenceStore;
41+
private final String message;
42+
private final String dialogTitle;
43+
private final Shell shell;
44+
45+
private HotCodeReplaceErrorDialogSimRunnable(IStatus status, String toggleMessage, String prefAlertObsoleteMethods, String toggleMessage2, IPreferenceStore preferenceStore, String message, String dialogTitle, Shell shell) {
46+
this.status = status;
47+
this.toggleMessage = toggleMessage;
48+
this.prefAlertObsoleteMethods = prefAlertObsoleteMethods;
49+
this.toggleMessage2 = toggleMessage2;
50+
this.preferenceStore = preferenceStore;
51+
this.message = message;
52+
this.dialogTitle = dialogTitle;
53+
this.shell = shell;
54+
}
55+
56+
@Override
57+
public void run() {
58+
class HotCodeReplaceErrorDialogExtension extends HotCodeReplaceErrorDialog {
59+
private HotCodeReplaceErrorDialogExtension(Shell parentShell, String dialogTitle, String message, IStatus status, String preferenceKey, String toggleMessage, String toggleMessage2, IPreferenceStore store, IDebugTarget target) {
60+
super(parentShell, dialogTitle, message, status, preferenceKey, toggleMessage, toggleMessage2, store, target);
61+
}
62+
63+
@Override
64+
public void buttonPressed(int id) {
65+
super.buttonPressed(id);
66+
}
67+
}
68+
69+
HotCodeReplaceErrorDialogExtension errorDialog = new HotCodeReplaceErrorDialogExtension(shell, dialogTitle, message, status, prefAlertObsoleteMethods, toggleMessage, toggleMessage2, preferenceStore, new TestDebugTarget());
70+
final boolean originalMode = ErrorDialog.AUTOMATED_MODE;
71+
ErrorDialog.AUTOMATED_MODE = false;
72+
try {
73+
errorDialog.create();
74+
errorDialog.getShell().addShellListener(new ShellAdapter() {
75+
@Override
76+
public void shellActivated(ShellEvent e) {
77+
// To see dialog: processUiEvents(500);
78+
processUiEvents();
79+
errorDialog.buttonPressed(IDialogConstants.OK_ID);
80+
}
81+
});
82+
errorDialog.open();
83+
} catch (Exception e) {
84+
throw new RuntimeException(e);
85+
} finally {
86+
ErrorDialog.AUTOMATED_MODE = originalMode;
87+
errorDialog.close();
88+
}
89+
}
90+
}
91+
92+
public HotCodeReplaceErrorDialogTest(String name) {
93+
super(name);
94+
}
95+
96+
@Test
97+
public void testHotCodeReplaceErrorDialog() {
98+
Shell shell = JDIDebugUIPlugin.getActiveWorkbenchShell();
99+
final String vmName = "Dummy VM";
100+
final String dialogTitle = DebugUIMessages.JDIDebugUIPlugin_Obsolete_methods_remain_1;
101+
final String message = NLS.bind(DebugUIMessages.JDIDebugUIPlugin__0__contains_obsolete_methods_1, new Object[] { vmName });
102+
final IStatus status = new Status(IStatus.WARNING, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.WARNING, DebugUIMessages.JDIDebugUIPlugin_Stepping_may_be_hazardous_1, null);
103+
final String toggleMessage = DebugUIMessages.JDIDebugUIPlugin_2;
104+
final String toggleMessage2 = DebugUIMessages.JDIDebugUIPlugin_5;
105+
IPreferenceStore preferenceStore = JDIDebugUIPlugin.getDefault().getPreferenceStore();
106+
String prefAlertObsoleteMethods = IJDIPreferencesConstants.PREF_ALERT_OBSOLETE_METHODS;
107+
108+
Runnable dialogSimRunnable = new HotCodeReplaceErrorDialogSimRunnable(status, toggleMessage, prefAlertObsoleteMethods, toggleMessage2, preferenceStore, message, dialogTitle, shell);
109+
sync(dialogSimRunnable);
110+
}
111+
}

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/ErrorDialogWithToggle.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ protected void buttonPressed(int id, IDebugTarget target) {
105105
if (id == IDialogConstants.OK_ID) { // was the OK button pressed?
106106
storePreference(target);
107107
}
108-
buttonPressed(id);
109108
}
110109

111110
@Override

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/HotCodeReplaceErrorDialog.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ public void run() {
153153
okPressed();
154154
} else {
155155
super.buttonPressed(id, target);
156+
super.buttonPressed(id);
156157
}
157158
}
158159

0 commit comments

Comments
 (0)