diff --git a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
index 1413400308..c95cd608dd 100644
--- a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
@@ -39,7 +39,7 @@ Require-Bundle: org.eclipse.ui.ide;resolution:=optional,
org.eclipse.jdt.core;bundle-version="[3.34.0,4.0.0)",
org.eclipse.jdt.ui;bundle-version="[3.33.0,4.0.0)",
org.eclipse.jdt.launching;bundle-version="[3.20.0,4.0.0)",
- org.eclipse.jdt.debug;bundle-version="[3.21.0,4.0.0)",
+ org.eclipse.jdt.debug;bundle-version="[3.23.0,4.0.0)",
org.eclipse.jdt.debug.ui;bundle-version="[3.13.0,4.0.0)",
org.eclipse.debug.core;bundle-version="[3.22.0,4.0.0)",
org.eclipse.debug.ui;bundle-version="[3.13.0,4.0.0)",
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/TriggerPointBreakpointsTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/TriggerPointBreakpointsTests.java
index adff135727..93dc00ca64 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/TriggerPointBreakpointsTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/TriggerPointBreakpointsTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 IBM Corporation and others.
+ * Copyright (c) 2016, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,6 +14,7 @@
package org.eclipse.jdt.debug.tests.breakpoints;
import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaPrimitiveValue;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
@@ -69,4 +70,69 @@ public void testTriggerPointBreakpoint() throws Exception {
removeAllBreakpoints();
}
}
+
+ public void testTriggerPointBreakpointWithResume() throws Exception {
+ String typeName = "TriggerPoint_01";
+ IJavaLineBreakpoint bp1 = createLineBreakpoint(20, typeName);
+ IJavaLineBreakpoint bp2 = createLineBreakpoint(21, typeName);
+ bp1.setTriggerPoint(true);
+ bp1.setSuspendPolicy(IJavaBreakpoint.RESUME_ON_HIT); // Resume mode
+ IJavaThread thread = null;
+ try {
+ thread = launchToLineBreakpoint(typeName, bp2);
+
+ IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame();
+ int lineNumber = frame.getLineNumber();
+ assertEquals("Breakpoint should resume and hit next breakpoint", 21, lineNumber);
+ bp1.delete();
+ bp2.delete();
+ } finally {
+ terminateAndRemove(thread);
+ removeAllBreakpoints();
+ }
+ }
+
+ public void testTriggerPointBreakpointWithResumeAndCondition() throws Exception {
+ String typeName = "TriggerPoint_01";
+ IJavaLineBreakpoint bp1 = createLineBreakpoint(20, typeName);
+ IJavaLineBreakpoint bp2 = createLineBreakpoint(21, typeName);
+ bp1.setTriggerPoint(true);
+ bp1.setConditionEnabled(true);
+ bp1.setCondition("false"); // this wont let breakpoint to resume
+ bp1.setSuspendPolicy(IJavaBreakpoint.RESUME_ON_HIT); // Resume mode
+ IJavaThread thread = null;
+ try {
+ thread = launchToBreakpoint(typeName);
+ IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame();
+ int lineNumber = frame.getLineNumber();
+ assertEquals("Breakpoint should not resume as condition is false", 20, lineNumber);
+ bp1.delete();
+ bp2.delete();
+ } finally {
+ terminateAndRemove(thread);
+ removeAllBreakpoints();
+ }
+ }
+
+ public void testTriggerPointBreakpointWithResumeAndConditionAsTrue() throws Exception {
+ String typeName = "TriggerPoint_01";
+ IJavaLineBreakpoint bp1 = createLineBreakpoint(20, typeName);
+ IJavaLineBreakpoint bp2 = createLineBreakpoint(21, typeName);
+ bp1.setTriggerPoint(true);
+ bp1.setConditionEnabled(true);
+ bp1.setCondition("true"); // this will let breakpoint to resume
+ bp1.setSuspendPolicy(IJavaBreakpoint.RESUME_ON_HIT); // Resume mode
+ IJavaThread thread = null;
+ try {
+ thread = launchToBreakpoint(typeName);
+ IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame();
+ int lineNumber = frame.getLineNumber();
+ assertEquals("Breakpoint should not resume as condition is false", 21, lineNumber);
+ bp1.delete();
+ bp2.delete();
+ } finally {
+ terminateAndRemove(thread);
+ removeAllBreakpoints();
+ }
+ }
}
diff --git a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
index 16073a15cb..5dd11bc164 100644
--- a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.debug.ui; singleton:=true
-Bundle-Version: 3.14.100.qualifier
+Bundle-Version: 3.15.0.qualifier
Bundle-Activator: org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -40,7 +40,7 @@ Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)",
org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)",
org.eclipse.jdt.core;bundle-version="[3.40.0,4.0.0)",
org.eclipse.debug.ui;bundle-version="[3.13.400,4.0.0)",
- org.eclipse.jdt.debug;bundle-version="[3.21.0,4.0.0)",
+ org.eclipse.jdt.debug;bundle-version="[3.23.0,4.0.0)",
org.eclipse.jdt.launching;bundle-version="[3.23.0,4.0.0)",
org.eclipse.jdt.ui;bundle-version="[3.33.0,4.0.0)",
org.eclipse.core.runtime;bundle-version="[3.30.0,4.0.0)",
diff --git a/org.eclipse.jdt.debug.ui/pom.xml b/org.eclipse.jdt.debug.ui/pom.xml
index 6db08dc643..3a34032609 100644
--- a/org.eclipse.jdt.debug.ui/pom.xml
+++ b/org.eclipse.jdt.debug.ui/pom.xml
@@ -18,7 +18,7 @@
org.eclipse.jdt
org.eclipse.jdt.debug.ui
- 3.14.100-SNAPSHOT
+ 3.15.0-SNAPSHOT
eclipse-plugin
true
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/breakpoints/JavaBreakpointConditionEditor.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/breakpoints/JavaBreakpointConditionEditor.java
index 6d4788c067..9c3c1708f4 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/breakpoints/JavaBreakpointConditionEditor.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/breakpoints/JavaBreakpointConditionEditor.java
@@ -26,12 +26,14 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
@@ -142,8 +144,7 @@ public final class JavaBreakpointConditionEditor extends AbstractJavaBreakpointE
private IAction fViewRedoAction;
private OperationHistoryActionHandler fViewerUndoAction;
private OperationHistoryActionHandler fViewerRedoAction;
-
-
+ private boolean isResumeOnHit;
/**
* Property id for breakpoint condition expression.
*/
@@ -361,6 +362,9 @@ public Control createControl(Composite parent) {
public void widgetSelected(SelectionEvent e) {
boolean checked = fConditional.getSelection();
setEnabled(checked, true);
+ if (isResumeOnHit) {
+ updateConditionTextOnResume();
+ }
setDirty(PROP_CONDITION_ENABLED);
}
});
@@ -455,6 +459,9 @@ public void widgetDisposed(DisposeEvent e) {
dispose();
}
});
+ if (isResumeOnHit) {
+ updateConditionTextOnResume();
+ }
return parent;
}
@@ -592,6 +599,19 @@ private void disposeViewerUndoRedoActions() {
* @param focus true if focus should be set, false otherwise
*/
private void setEnabled(boolean enabled, boolean focus) {
+ try {
+ if (fBreakpoint != null) {
+ if (fBreakpoint.getSuspendPolicy() == IJavaBreakpoint.RESUME_ON_HIT) {
+ updateConditionTextOnResume();
+ } else {
+ fWhenTrue.setText(PropertyPageMessages.JavaBreakpointConditionEditor_1);
+ fWhenChange.setText(PropertyPageMessages.JavaBreakpointConditionEditor_2);
+ }
+ }
+ } catch (CoreException e) {
+ DebugUIPlugin.log(e);
+ }
+
fViewer.setEditable(enabled);
fViewer.getTextWidget().setEnabled(enabled);
fWhenChange.setEnabled(enabled);
@@ -843,4 +863,35 @@ private void checkIfUsedInBreakpointsView() {
}
}
+ /**
+ * Update label values in Condition editor for trigger points that resume on hit
+ *
+ * @since 3.15
+ */
+ public void updateConditionTextOnResume() {
+ fWhenTrue.setText(PropertyPageMessages.BreakpointResumeConditionalTrue);
+ fWhenChange.setText(PropertyPageMessages.BreakpointResumeConditionalValue);
+ }
+
+ /**
+ * Update label values in Condition editor for suspending breakpoints
+ *
+ * @since 3.15
+ */
+ public void updateConditionTextOnSuspend() {
+ fWhenTrue.setText(PropertyPageMessages.JavaBreakpointConditionEditor_1);
+ fWhenChange.setText(PropertyPageMessages.JavaBreakpointConditionEditor_2);
+ }
+
+ /**
+ * Set "Resume on hit" flag
+ *
+ * @see IJavaBreakpoint#RESUME_ON_HIT
+ *
+ * @since 3.15
+ */
+ public void setResumeOnHit(boolean resume) {
+ isResumeOnHit = resume;
+ }
+
}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.java
index 58a8aafecd..a6fbf90131 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.java
@@ -179,6 +179,7 @@ public class DebugUIMessages extends NLS {
public static String JDIModelPresentation_target_suspended;
public static String JDIModelPresentation_thread_filtered;
public static String JDIModelPresentation_uncaught_62;
+ public static String JDIModelPresentation_resume_on_hit;
// thread label keys are built programmatically
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties
index 6fef0fa103..28d6c87f80 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties
@@ -118,6 +118,7 @@ JDIModelPresentation_native_method=[native method]
JDIModelPresentation_not_available=not available
JDIModelPresentation_Suspend_VM=[Suspend VM]
JDIModelPresentation_collapsed_frames={0} collapsed frames
+JDIModelPresentation_resume_on_hit=[Resume on hit]
###############################################################################
# Thread label keys are built programmatically
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java
index 0bfa1b8fda..c031102792 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java
@@ -2023,6 +2023,10 @@ protected void appendSuspendPolicy(IJavaBreakpoint breakpoint, StringBuilder buf
buffer.append(' ');
buffer.append(DebugUIMessages.JDIModelPresentation_Suspend_VM);
}
+ if (breakpoint.getSuspendPolicy() == IJavaBreakpoint.RESUME_ON_HIT) {
+ buffer.append(' ');
+ buffer.append(DebugUIMessages.JDIModelPresentation_resume_on_hit);
+ }
}
protected void appendThreadFilter(IJavaBreakpoint breakpoint, StringBuilder buffer) throws CoreException {
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/StandardJavaBreakpointEditor.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/StandardJavaBreakpointEditor.java
index 843deec568..e36391bfd4 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/StandardJavaBreakpointEditor.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/StandardJavaBreakpointEditor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2016 IBM Corporation and others.
+ * Copyright (c) 2009, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -19,6 +19,7 @@
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
+import org.eclipse.jdt.debug.ui.breakpoints.JavaBreakpointConditionEditor;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.propertypages.PropertyPageMessages;
import org.eclipse.jface.util.Util;
@@ -44,9 +45,12 @@ public class StandardJavaBreakpointEditor extends AbstractJavaBreakpointEditor {
private Button fHitCountButton;
private Text fHitCountText;
private Button fSuspendThread;
+ private Button fResumeOnHit;
private Button fSuspendVM;
protected Button fTriggerPointButton;
+ private final JavaBreakpointConditionEditor javaBpConditionEditor;
+
/**
* Property id for hit count enabled state.
*/
@@ -67,6 +71,14 @@ public class StandardJavaBreakpointEditor extends AbstractJavaBreakpointEditor {
*/
public static final int PROP_TRIGGER_POINT = 0x1008;
+ public StandardJavaBreakpointEditor() {
+ this(null);
+ }
+
+ public StandardJavaBreakpointEditor(JavaBreakpointConditionEditor jb) {
+ javaBpConditionEditor = jb;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.debug.ui.breakpoints.AbstractJavaBreakpointEditor#createControl(org.eclipse.swt.widgets.Composite)
*/
@@ -87,18 +99,62 @@ protected Button createCheckButton(Composite parent, String text) {
* the parent composite
*/
protected void createTriggerPointButton(Composite parent) {
- Composite composite = SWTFactory.createComposite(parent, parent.getFont(), 1, 1, 0, 0, 0);
+ Composite composite = SWTFactory.createComposite(parent, parent.getFont(), 2, 1, 0, 0, 0);
fTriggerPointButton = createCheckButton(composite, PropertyPageMessages.JavaBreakpointPage_12);
-
+ fTriggerPointButton.setEnabled(true);
fTriggerPointButton.setSelection(isTriggerPoint());
fTriggerPointButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
+ boolean resumeOnHitEnabled = fResumeOnHit.isEnabled();
+ if (resumeOnHitEnabled) {
+ fResumeOnHit.setSelection(false);
+ fResumeOnHit.setEnabled(false);
+ } else {
+ fResumeOnHit.setEnabled(true);
+ }
+ if (isTriggerPoint()) {
+ if (suspendVmAndTreadNotSelected()) {
+ fSuspendThread.setSelection(true);
+ setConditionTextToSuspend();
+ }
+ } else {
+ if (resumeOnHitEnabled) {
+ if (suspendVmAndTreadNotSelected()) {
+ fSuspendThread.setSelection(true);
+ setConditionTextToSuspend();
+ }
+ } else {
+ setConditionTextToSuspend();
+ }
+ }
+
setDirty(PROP_TRIGGER_POINT);
}
+ private boolean suspendVmAndTreadNotSelected() {
+ return !fSuspendThread.getSelection() && !fSuspendVM.getSelection();
+ }
+ });
+ fResumeOnHit = SWTFactory.createRadioButton(composite, PropertyPageMessages.BreakpointResumeOnHit, 1);
+ fResumeOnHit.setLayoutData(new GridData());
+ fResumeOnHit.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (javaBpConditionEditor != null) {
+ if (fResumeOnHit.isEnabled()) {
+ javaBpConditionEditor.updateConditionTextOnResume();
+ }
+ if (fResumeOnHit.getSelection()) {
+ javaBpConditionEditor.setResumeOnHit(true);
+ }
+ }
+ setDirty(PROP_SUSPEND_POLICY);
+ fSuspendThread.setSelection(false);
+ fSuspendVM.setSelection(false);
+ fResumeOnHit.setEnabled(true);
+ }
});
-
}
protected Control createStandardControls(Composite parent) {
@@ -125,8 +181,9 @@ public void modifyText(ModifyEvent e) {
setDirty(PROP_HIT_COUNT);
}
});
+
SWTFactory.createLabel(composite, "", 1); // spacer //$NON-NLS-1$
- Composite radios = SWTFactory.createComposite(composite, composite.getFont(), 2, 1, GridData.FILL_HORIZONTAL, 0, 0);
+ Composite radios = SWTFactory.createComposite(composite, composite.getFont(), 3, 1, GridData.FILL_HORIZONTAL, 0, 0);
fSuspendThread = SWTFactory.createRadioButton(radios, processMnemonics(PropertyPageMessages.JavaBreakpointPage_7), 1);
fSuspendThread.setLayoutData(new GridData());
fSuspendVM = SWTFactory.createRadioButton(radios, processMnemonics(PropertyPageMessages.JavaBreakpointPage_8), 1);
@@ -134,12 +191,14 @@ public void modifyText(ModifyEvent e) {
fSuspendThread.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
+ setConditionTextToSuspend();
setDirty(PROP_SUSPEND_POLICY);
}
});
fSuspendVM.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
+ setConditionTextToSuspend();
setDirty(PROP_SUSPEND_POLICY);
}
});
@@ -189,6 +248,7 @@ protected void setBreakpoint(IJavaBreakpoint breakpoint) throws CoreException {
boolean hasHitCount = false;
String text = Util.ZERO_LENGTH_STRING;
boolean suspendThread = true;
+ boolean resumeOnHit = false;
if (breakpoint != null) {
enabled = true;
int hitCount = breakpoint.getHitCount();
@@ -197,6 +257,7 @@ protected void setBreakpoint(IJavaBreakpoint breakpoint) throws CoreException {
hasHitCount = true;
}
suspendThread= breakpoint.getSuspendPolicy() == IJavaBreakpoint.SUSPEND_THREAD;
+ resumeOnHit = breakpoint.getSuspendPolicy() == IJavaBreakpoint.RESUME_ON_HIT && isTriggerPoint();
}
fHitCountButton.setEnabled(enabled);
fHitCountButton.setSelection(enabled && hasHitCount);
@@ -204,8 +265,10 @@ protected void setBreakpoint(IJavaBreakpoint breakpoint) throws CoreException {
fHitCountText.setText(text);
fSuspendThread.setEnabled(enabled);
fSuspendVM.setEnabled(enabled);
- fSuspendThread.setSelection(suspendThread);
- fSuspendVM.setSelection(!suspendThread);
+ fResumeOnHit.setEnabled(isTriggerPoint());
+ fResumeOnHit.setSelection(resumeOnHit);
+ fSuspendThread.setSelection(suspendThread && !resumeOnHit);
+ fSuspendVM.setSelection(!suspendThread && !resumeOnHit);
fTriggerPointButton.setEnabled(enabled);
fTriggerPointButton.setSelection(isTriggerPoint());
setDirty(false);
@@ -238,6 +301,9 @@ public void doSave() throws CoreException {
if(fSuspendVM.getSelection()) {
suspendPolicy = IJavaBreakpoint.SUSPEND_VM;
}
+ if (fResumeOnHit.getSelection() && fTriggerPointButton.getSelection()) {
+ suspendPolicy = IJavaBreakpoint.RESUME_ON_HIT;
+ }
fBreakpoint.setSuspendPolicy(suspendPolicy);
int hitCount = -1;
if (fHitCountButton.getSelection()) {
@@ -329,4 +395,14 @@ private void storeTriggerPoint(IJavaBreakpoint breakpoint) throws CoreException
DebugPlugin.getDefault().getBreakpointManager().refreshTriggerpointDisplay();
}
+ private void setConditionTextToSuspend() {
+ if (fResumeOnHit.isEnabled()) {
+ fResumeOnHit.setSelection(false);
+ }
+ if (javaBpConditionEditor != null) {
+ javaBpConditionEditor.setResumeOnHit(false);
+ javaBpConditionEditor.updateConditionTextOnSuspend();
+ }
+ }
+
}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java
index cfbaa40587..d7ac508119 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java
@@ -335,8 +335,9 @@ protected void createTypeSpecificEditors(Composite parent) {
fEditor = new StandardJavaBreakpointEditor();
} else if (JavaLineBreakpoint.JAVA_LINE_BREAKPOINT.equals(type)) {
setTitle(PropertyPageMessages.JavaLineBreakpointPage_18);
+ JavaBreakpointConditionEditor javaBpConditionEditor = new JavaBreakpointConditionEditor(null);
fEditor = new CompositeBreakpointEditor(new AbstractJavaBreakpointEditor[]
- {new StandardJavaBreakpointEditor(), new JavaBreakpointConditionEditor(null)});
+ { new StandardJavaBreakpointEditor(javaBpConditionEditor), javaBpConditionEditor });
} else if (JavaExceptionBreakpoint.JAVA_EXCEPTION_BREAKPOINT.equals(type)) {
setTitle(PropertyPageMessages.JavaExceptionBreakpointPage_5);
fEditor = new ExceptionBreakpointEditor();
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.java
index bf17a73922..78b6a11fb5 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2019 IBM Corporation and others.
+ * Copyright (c) 2003, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -112,11 +112,14 @@ public class PropertyPageMessages extends NLS {
public static String VMCapabilitiesPropertyPage_29;
public static String VMCapabilitiesPropertyPage_3;
-
public static String VMCapabilitiesPropertyPage_30;
public static String VMCapabilitiesPropertyPage_31;
public static String VMCapabilitiesPropertyPage_4;
public static String VMCapabilitiesPropertyPage_6;
public static String VMCapabilitiesPropertyPage_9;
+ public static String BreakpointResumeOnHit;
+ public static String BreakpointResumeConditionalTrue;
+ public static String BreakpointResumeConditionalValue;
+
}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.properties
index ff31c098c4..d734043042 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/PropertyPageMessages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2003, 2019 IBM Corporation and others.
+# Copyright (c) 2003, 2025 IBM Corporation and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
@@ -91,3 +91,6 @@ VMCapabilitiesPropertyPage_28=&Hot Code Replace
VMCapabilitiesPropertyPage_29=&Stepping
VMCapabilitiesPropertyPage_30=&General
VMCapabilitiesPropertyPage_31=This page displays optional debug capabilities that may be supported by the selected VM.
+BreakpointResumeOnHit=Continue execution on hit
+BreakpointResumeConditionalTrue=Resume when 'true'
+BreakpointResumeConditionalValue=Resume when value changes
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaBreakpoint.java
index 1d3131a913..0a5322e241 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaBreakpoint.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -47,6 +47,12 @@ public interface IJavaBreakpoint extends IBreakpoint, ITriggerPoint {
*/
public static final int SUSPEND_THREAD = 2;
+ /**
+ * Suspend policy constant indicating a breakpoint will not suspend the target VM when hit.
+ *
+ * @since 3.23
+ */
+ public static final int RESUME_ON_HIT = 3;
/**
* Returns whether this breakpoint is installed in at least one debug
* target.
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java
index 1ee949ea4d..f864f17020 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2022 IBM Corporation and others.
+ * Copyright (c) 2000, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -702,7 +702,7 @@ protected void addToTargetForLocalType(JDIDebugTarget target, String enclosingTy
*/
protected int getJDISuspendPolicy() throws CoreException {
int breakpointPolicy = getSuspendPolicy();
- if (breakpointPolicy == IJavaBreakpoint.SUSPEND_THREAD) {
+ if (breakpointPolicy == IJavaBreakpoint.SUSPEND_THREAD || breakpointPolicy == IJavaBreakpoint.RESUME_ON_HIT ) {
return EventRequest.SUSPEND_EVENT_THREAD;
}
return EventRequest.SUSPEND_ALL;
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
index c8063b6b46..cc5b29f49d 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
@@ -1441,8 +1441,12 @@ private boolean handleSuspendForBreakpointInternal(JavaBreakpoint breakpoint) {
}
}
catch (CoreException e) {
- e.printStackTrace();
+ logError(e);
}
+
+ // Condition for a trigger breakpoint that is set to resume on hit
+ boolean resumeOnHit = true;
+
// Evaluate breakpoint condition (if any). The condition is evaluated
// regardless of the current suspend vote status, since breakpoint
// listeners
@@ -1457,10 +1461,14 @@ private boolean handleSuspendForBreakpointInternal(JavaBreakpoint breakpoint) {
ConditionalBreakpointHandler handler = new ConditionalBreakpointHandler();
int vote = handler.breakpointHit(this, breakpoint);
if (vote == IJavaBreakpointListener.DONT_SUSPEND) {
- // condition is false, breakpoint is not hit
- synchronized (this) {
- fSuspendVoteInProgress = false;
- return false;
+ if (policy == IJavaBreakpoint.RESUME_ON_HIT) {
+ resumeOnHit = false;
+ } else {
+ // condition is false, breakpoint is not hit
+ synchronized (this) {
+ fSuspendVoteInProgress = false;
+ return false;
+ }
}
}
if (handler.hasErrors()) {
@@ -1478,9 +1486,21 @@ private boolean handleSuspendForBreakpointInternal(JavaBreakpoint breakpoint) {
}
}
+ try {
+ if (resumeOnHit && breakpoint.getSuspendPolicy() == IJavaBreakpoint.RESUME_ON_HIT) {
+ synchronized (this) {
+ fSuspendVoteInProgress = false;
+ return false; // Won't be suspended
+ }
+ }
+ } catch (CoreException e) {
+ logError(e);
+ }
+
// poll listeners without holding lock on thread
boolean suspend = true;
try {
+
suspend = JDIDebugPlugin.getDefault().fireBreakpointHit(this,
breakpoint);
} finally {