Skip to content

Commit 6f9ee35

Browse files
authored
Merge branch 'eclipse-jdt:master' into master
2 parents cb702b4 + abeab58 commit 6f9ee35

28 files changed

Lines changed: 307 additions & 106 deletions

File tree

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,17 @@
128128
import org.eclipse.jdt.debug.tests.core.LiteralTests17;
129129
import org.eclipse.jdt.debug.tests.refactoring.MemberParser;
130130
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
131+
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
131132
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
132133
import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTEvaluationEngine;
133134
import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
134135
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
135136
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
136137
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
137138
import org.eclipse.jdt.launching.IVMInstall;
139+
import org.eclipse.jdt.launching.IVMInstallChangedListener;
138140
import org.eclipse.jdt.launching.JavaRuntime;
141+
import org.eclipse.jdt.launching.PropertyChangeEvent;
139142
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
140143
import org.eclipse.jface.dialogs.ErrorDialog;
141144
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
@@ -170,6 +173,8 @@
170173
@SuppressWarnings("deprecation")
171174
public abstract class AbstractDebugTest extends TestCase implements IEvaluationListener {
172175

176+
private static boolean setupFirstTest = false;
177+
173178
public static final String MULTI_OUTPUT_PROJECT_NAME = "MultiOutput";
174179
public static final String BOUND_EE_PROJECT_NAME = "BoundEE";
175180
public static final String ONE_FOUR_PROJECT_NAME = "DebugTests";
@@ -264,6 +269,11 @@ public AbstractDebugTest(String name) {
264269

265270
@Override
266271
protected void setUp() throws Exception {
272+
if (!setupFirstTest) {
273+
setupFirstTest = true;
274+
TestUtil.logInfo("SETTING UP TESTS");
275+
JavaRuntime.addVMInstallChangedListener(new LogVMInstallChanges());
276+
}
267277
TestUtil.logInfo("SETUP " + getClass().getSimpleName() + "." + getName());
268278
super.setUp();
269279
setPreferences();
@@ -1420,7 +1430,7 @@ protected Object launchAndWait(ILaunchConfiguration configuration, DebugEventWai
14201430
* if the event is never received.
14211431
*/
14221432
protected Object launchAndWait(ILaunchConfiguration configuration, String mode, DebugEventWaiter waiter, boolean register) throws CoreException {
1423-
ILaunch launch = configuration.launch(mode, null, false, register);
1433+
ILaunch launch = configuration.launch(mode, new TimeoutMonitor(DEFAULT_TIMEOUT), false, register);
14241434
Object suspendee= waiter.waitForEvent();
14251435
if (suspendee == null) {
14261436
StringBuilder buf = new StringBuilder();
@@ -3090,4 +3100,34 @@ private static String toString(Collection<IMarker> markers) {
30903100
public interface StackFrameSupplier {
30913101
IJavaStackFrame get() throws Exception;
30923102
}
3103+
3104+
private static void logVMChange(String message, IVMInstall vm) {
3105+
String detailed = message + " " + vm.getName() + ", location: " + vm.getInstallLocation();
3106+
IStatus status = new Status(IStatus.INFO, JDIDebugPlugin.getUniqueIdentifier(), detailed, null);
3107+
JDIDebugPlugin.log(status);
3108+
}
3109+
3110+
private static class LogVMInstallChanges implements IVMInstallChangedListener {
3111+
3112+
@Override
3113+
public void vmRemoved(IVMInstall vm) {
3114+
logVMChange("VM removed", vm);
3115+
}
3116+
3117+
@Override
3118+
public void vmChanged(PropertyChangeEvent event) {
3119+
}
3120+
3121+
@Override
3122+
public void vmAdded(IVMInstall vm) {
3123+
logVMChange("VM added", vm);
3124+
3125+
}
3126+
3127+
@Override
3128+
public void defaultVMInstallChanged(IVMInstall previous, IVMInstall current) {
3129+
logVMChange("Default VM changed", current);
3130+
}
3131+
3132+
}
30933133
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Simeon Andreev 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+
* Simeon Andreev - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.jdt.debug.tests;
15+
16+
import org.eclipse.core.runtime.IProgressMonitor;
17+
18+
/**
19+
* A progress monitor which reports that the task is cancelled if a timeout occurs. The starting time for the timeout is the creation of the monitor.
20+
*/
21+
public class TimeoutMonitor implements IProgressMonitor {
22+
23+
private final long timeoutMs;
24+
private final long startMs;
25+
26+
TimeoutMonitor(long timeoutMs) {
27+
this.timeoutMs = timeoutMs;
28+
this.startMs = System.currentTimeMillis();
29+
}
30+
31+
@Override
32+
public void beginTask(String name, int totalWork) {
33+
}
34+
35+
@Override
36+
public void done() {
37+
}
38+
39+
@Override
40+
public void internalWorked(double work) {
41+
}
42+
43+
@Override
44+
public boolean isCanceled() {
45+
return System.currentTimeMillis() - startMs > timeoutMs;
46+
}
47+
48+
@Override
49+
public void setCanceled(boolean value) {
50+
throw new UnsupportedOperationException();
51+
}
52+
53+
@Override
54+
public void setTaskName(String name) {
55+
}
56+
57+
@Override
58+
public void subTask(String name) {
59+
}
60+
61+
@Override
62+
public void worked(int work) {
63+
}
64+
65+
}

org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ModuleOptionsTests.java

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@
2525
import org.eclipse.jdt.core.JavaCore;
2626
import org.eclipse.jdt.core.JavaModelException;
2727
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
28+
import org.eclipse.jdt.debug.tests.TestUtil;
29+
import org.eclipse.jdt.launching.IVMInstall;
2830
import org.eclipse.jdt.launching.JavaRuntime;
31+
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
32+
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
2933

3034
public class ModuleOptionsTests extends AbstractDebugTest {
3135

36+
private static final String JAVASE_9 = "JavaSE-9";
37+
3238
private static final String ASSUMED_DEFAULT_MODULES_9 = "java.se," //
3339
// + "javafx.base,javafx.controls,javafx.fxml,javafx.graphics,javafx.media,javafx.swing,javafx.web," REMOVED in 10
3440
+ "jdk.accessibility,jdk.attach,jdk.compiler,jdk.dynalink,jdk.httpserver,"//
@@ -63,11 +69,27 @@ public class ModuleOptionsTests extends AbstractDebugTest {
6369
+ "jdk.unsupported.desktop," //
6470
+ "jdk.xml.dom";
6571

72+
private IVMInstall defaultVM9;
6673

6774
public ModuleOptionsTests(String name) {
6875
super(name);
6976
}
7077

78+
@Override
79+
protected void setUp() throws Exception {
80+
super.setUp();
81+
prepareExecutionEnvironment9();
82+
}
83+
84+
@Override
85+
protected void tearDown() throws Exception {
86+
try {
87+
restoreExecutionEnvironment9();
88+
} finally {
89+
super.tearDown();
90+
}
91+
}
92+
7193
@Override
7294
protected IJavaProject getProjectContext() {
7395
return get9Project();
@@ -112,8 +134,9 @@ private int indexOfJREContainer(IClasspathEntry[] rawClasspath) {
112134
return -1;
113135
}
114136

115-
public void testAddModules1() throws JavaModelException {
137+
public void testAddModules1() throws Exception {
116138
IJavaProject javaProject = getProjectContext();
139+
checkVMInstall(javaProject);
117140
List<String> defaultModules = getDefaultModules(javaProject);
118141
defaultModules.add("jdk.crypto.cryptoki"); // requires jdk.crypto.ec up to Java 21
119142
try {
@@ -135,8 +158,9 @@ public void testAddModules1() throws JavaModelException {
135158
}
136159
}
137160

138-
public void testLimitModules_release9() throws CoreException {
161+
public void testLimitModules_release9() throws Exception {
139162
IJavaProject javaProject = getProjectContext();
163+
checkVMInstall(javaProject);
140164
try {
141165
javaProject.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
142166
List<String> defaultModules = getDefaultModules(javaProject);
@@ -153,7 +177,7 @@ public void testLimitModules_release9() throws CoreException {
153177
+ "jdk.net," //
154178
+ "jdk.nio.mapmode," //
155179
// + "jdk.packager,jdk.packager.services,jdk.plugin.dom,"
156-
// + "jdk.scripting.nashorn,"
180+
// + "jdk.scripting.nashorn,"
157181
+ "jdk.sctp,"
158182
+ "jdk.security.auth,jdk.security.jgss,jdk.unsupported," //
159183
+ "jdk.unsupported.desktop,jdk.xml.dom";
@@ -178,8 +202,10 @@ public void testLimitModules_release9() throws CoreException {
178202
}
179203
}
180204

181-
public void testLimitModules1() throws JavaModelException {
205+
public void testLimitModules1() throws Exception {
182206
IJavaProject javaProject = getProjectContext();
207+
javaProject.setOption(JavaCore.COMPILER_RELEASE, JavaCore.DISABLED);
208+
checkVMInstall(javaProject);
183209
List<String> defaultModules = getDefaultModules(javaProject);
184210
String expectedModules;
185211
String moduleList = String.join(",", defaultModules);
@@ -218,4 +244,40 @@ public void testLimitModules1() throws JavaModelException {
218244
removeClasspathAttributesFromSystemLibrary(javaProject);
219245
}
220246
}
247+
248+
private void checkVMInstall(IJavaProject javaProject) throws CoreException {
249+
IVMInstall defaultVm = JavaRuntime.getDefaultVMInstall();
250+
IVMInstall vm = JavaRuntime.getVMInstall(javaProject);
251+
assertEquals("Expected default VM but got: " + vm.getInstallLocation(), defaultVm.getName(), vm.getName());
252+
}
253+
254+
/**
255+
* JDT tests run in different environments where different major JVM installations might be selected as "default" JVM for a specific Execution Environment (EE).
256+
* This test cases project requires JavaSE-9 EE, which can be resolved to e.g. Java 11, 17 or 21, depending on the installed JVMs.
257+
* JVM modules vary between Java major versions, while we need a stable set of modules for the test case.
258+
* Therefore we "pin" the JVM used for the JavaSE-9 EE to the JVM on which the tests are executed - to avoid tests failing in different test environments.
259+
*/
260+
private void prepareExecutionEnvironment9() {
261+
IVMInstall vm = JavaRuntime.getDefaultVMInstall();
262+
IExecutionEnvironment environment9 = getExecutionEnvironment9();
263+
defaultVM9 = environment9.getDefaultVM();
264+
environment9.setDefaultVM(vm);
265+
TestUtil.logInfo("Set VM \"" + vm.getName() + "\" for execution environments: " + environment9.getId());
266+
}
267+
268+
private void restoreExecutionEnvironment9() {
269+
IExecutionEnvironment environment9 = getExecutionEnvironment9();
270+
environment9.setDefaultVM(defaultVM9);
271+
TestUtil.logInfo("Restored default VM for execution environment: " + environment9.getId());
272+
}
273+
274+
private static IExecutionEnvironment getExecutionEnvironment9() {
275+
IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
276+
IExecutionEnvironment[] environments = manager.getExecutionEnvironments();
277+
return Arrays.stream(environments).filter(ModuleOptionsTests::isEnvironment9).findFirst().orElseThrow();
278+
}
279+
280+
private static boolean isEnvironment9(IExecutionEnvironment environment) {
281+
return JAVASE_9.equals(environment.getId());
282+
}
221283
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,4 +474,6 @@ public class DebugUIMessages extends NLS {
474474

475475
public static String ListSameElementsFor2;
476476
public static String fExceptionBreakpointMsg;
477+
478+
protected static String JavaDebugOptionsManager_Lambda_Breakpoint;
477479
}

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ JDIModelPresentation_no_suspended_threads=[toString() unavailable - no suspended
297297

298298
JavaDebugOptionsManager_Breakpoint___1=Breakpoint:
299299
JavaDebugOptionsManager_Method_breakpoint___2=Method breakpoint:
300+
JavaDebugOptionsManager_Lambda_Breakpoint=Lambda Breakpoint:
300301
JavaDebugOptionsManager_Watchpoint___3=Watchpoint:
301302
JavaDebugOptionsManager_0=Initialize Java Debug Options
302303
JavaDebugOptionsManager_exceptionRecurrence_dialogTitle=Repeated exception occurrence

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

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2025 IBM Corporation and others.
2+
* Copyright (c) 2000, 2026 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -21,6 +21,7 @@
2121

2222
import org.eclipse.core.resources.IMarker;
2323
import org.eclipse.core.resources.IResource;
24+
import org.eclipse.core.resources.ResourcesPlugin;
2425
import org.eclipse.core.runtime.CoreException;
2526
import org.eclipse.core.runtime.IAdaptable;
2627
import org.eclipse.debug.core.DebugException;
@@ -45,8 +46,13 @@
4546
import org.eclipse.debug.ui.IDebugModelPresentationExtension;
4647
import org.eclipse.debug.ui.IDebugUIConstants;
4748
import org.eclipse.debug.ui.IValueDetailListener;
49+
import org.eclipse.jdt.core.IJavaModel;
50+
import org.eclipse.jdt.core.IJavaProject;
4851
import org.eclipse.jdt.core.IMember;
52+
import org.eclipse.jdt.core.IOrdinaryClassFile;
4953
import org.eclipse.jdt.core.IType;
54+
import org.eclipse.jdt.core.JavaCore;
55+
import org.eclipse.jdt.core.JavaModelException;
5056
import org.eclipse.jdt.core.Signature;
5157
import org.eclipse.jdt.debug.core.IJavaArray;
5258
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
@@ -69,6 +75,7 @@
6975
import org.eclipse.jdt.debug.core.IJavaValue;
7076
import org.eclipse.jdt.debug.core.IJavaVariable;
7177
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
78+
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
7279
import org.eclipse.jdt.internal.debug.core.breakpoints.JavaExceptionBreakpoint;
7380
import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIAllInstancesValue;
7481
import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIReturnValueVariable;
@@ -1187,6 +1194,16 @@ public IEditorInput getEditorInput(Object item) {
11871194
return new LocalFileStorageEditorInput(localFileStorage);
11881195
}
11891196
if (item instanceof ZipEntryStorage zipEntryStorage) {
1197+
String typeName = getTypeName(zipEntryStorage);
1198+
if (typeName != null) {
1199+
IType type = findTypeInWorkspace(typeName);
1200+
if (type != null) {
1201+
IEditorInput input = getClassFileEditorInput(type);
1202+
if (input != null) {
1203+
return input;
1204+
}
1205+
}
1206+
}
11901207
return new ZipEntryStorageEditorInput(zipEntryStorage);
11911208
}
11921209
// for types that correspond to external files, return null so we do not
@@ -1199,6 +1216,44 @@ public IEditorInput getEditorInput(Object item) {
11991216
return EditorUtility.getEditorInput(item);
12001217
}
12011218

1219+
private static String getTypeName(ZipEntryStorage storage) {
1220+
String entryName = storage.getZipEntry().getName();
1221+
if (!entryName.endsWith(".java")) { //$NON-NLS-1$
1222+
return null;
1223+
}
1224+
entryName = entryName.substring(0, entryName.length() - ".java".length()); //$NON-NLS-1$
1225+
return entryName.replace('/', '.');
1226+
}
1227+
1228+
private static IEditorInput getClassFileEditorInput(IType type) {
1229+
try {
1230+
IOrdinaryClassFile classFile = type.getClassFile();
1231+
if (classFile != null && classFile.exists()) {
1232+
return EditorUtility.getEditorInput(classFile);
1233+
}
1234+
} catch (Exception e) {
1235+
}
1236+
return null;
1237+
}
1238+
1239+
private static IType findTypeInWorkspace(String typeName) {
1240+
try {
1241+
IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
1242+
for (IJavaProject jp : model.getJavaProjects()) {
1243+
if (!jp.exists()) {
1244+
continue;
1245+
}
1246+
IType type = jp.findType(typeName);
1247+
if (type != null && type.exists()) {
1248+
return type;
1249+
}
1250+
}
1251+
} catch (JavaModelException e) {
1252+
JDIDebugPlugin.log(e);
1253+
}
1254+
return null;
1255+
}
1256+
12021257
/**
12031258
* @see IDebugModelPresentation#getEditorId(IEditorInput, Object)
12041259
*/

0 commit comments

Comments
 (0)