Skip to content

Commit f1352a2

Browse files
Merge branch 'eclipse-platform:master' into issue-472-build_block_user_action
2 parents 7badcec + 9e339b2 commit f1352a2

File tree

166 files changed

+986
-435
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

166 files changed

+986
-435
lines changed

Jenkinsfile

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@ pipeline {
2929
post {
3030
always {
3131
archiveArtifacts artifacts: '.*log,**/target/**/.*log', allowEmptyArchive: true
32-
junit '**/target/surefire-reports/TEST-*.xml'
32+
junit allowEmptyResults: true, testResults: '**/target/surefire-reports/TEST-*.xml'
3333
discoverGitReferenceBuild referenceJob: 'eclipse.platform/master'
34-
recordIssues(publishAllIssues:false, ignoreQualityGate:true,
35-
tool: eclipse(name: 'Compiler and API Tools', pattern: '**/target/compilelogs/*.xml'),
36-
qualityGates: [[threshold: 1, type: 'DELTA', unstable: true]])
37-
recordIssues publishAllIssues:false, tools: [mavenConsole(), javaDoc()]
34+
recordIssues enabledForFailure: true, publishAllIssues:false, ignoreQualityGate:true,
35+
tools: [
36+
eclipse(name: 'Compiler', pattern: '**/target/compilelogs/*.xml'),
37+
issues(name: 'API Tools', id: 'apitools', pattern: '**/target/apianalysis/*.xml')
38+
],
39+
qualityGates: [[threshold: 1, type: 'DELTA', unstable: true]]
40+
recordIssues enabledForFailure: true, publishAllIssues:false, tools: [mavenConsole(), javaDoc()]
3841
}
3942
}
4043
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ For additional documentation, please refer to the [docs directory](./docs) and [
3838

3939
## Issue Tracking
4040

41-
This project uses Github to track ongoing development and issues. In case you have an issue, please read the information about Eclipse being a [community project](https://github.com/eclipse-platform#community) and bear in mind that this project is almost entirely developed by volunteers. So the contributors may not be able to look into every reported issue. You will also find the information about [how to find and report issues](https://github.com/eclipse-platform#reporting-issues) in repositories of the `eclipse-platform` organization there. Be sure to search for existing issues before you create another one.
41+
This project uses GitHub to track ongoing development and issues. In case you have an issue, please read the information about Eclipse being a [community project](https://github.com/eclipse-platform#community) and bear in mind that this project is almost entirely developed by volunteers. So the contributors may not be able to look into every reported issue. You will also find the information about [how to find and report issues](https://github.com/eclipse-platform#reporting-issues) in repositories of the `eclipse-platform` organization there. Be sure to search for existing issues before you create another one.
4242

4343
In case you want to report an issue that is specific to this `eclipse.platform` repository, you can [find existing issues](https://github.com/eclipse-platform/eclipse.platform/issues) or [create new issues](https://github.com/eclipse-platform/eclipse.platform/issues/new) within this repository.
4444

debug/org.eclipse.debug.core/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.debug.core; singleton:=true
5-
Bundle-Version: 3.22.100.qualifier
5+
Bundle-Version: 3.23.0.qualifier
66
Bundle-Activator: org.eclipse.debug.core.DebugPlugin
77
Bundle-Vendor: %providerName
88
Bundle-Localization: plugin

debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java

Lines changed: 117 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2021 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 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
@@ -22,9 +22,12 @@
2222
import java.nio.charset.StandardCharsets;
2323
import java.text.MessageFormat;
2424
import java.util.ArrayList;
25+
import java.util.Comparator;
2526
import java.util.HashMap;
27+
import java.util.LinkedHashMap;
2628
import java.util.List;
2729
import java.util.Map;
30+
import java.util.Optional;
2831

2932
import javax.xml.parsers.DocumentBuilder;
3033
import javax.xml.parsers.FactoryConfigurationError;
@@ -170,6 +173,14 @@ public class DebugPlugin extends Plugin {
170173
*/
171174
public static final String EXTENSION_POINT_PROCESS_FACTORIES = "processFactories"; //$NON-NLS-1$
172175

176+
/**
177+
* Simple identifier constant (value <code>"execFactories"</code>) for the
178+
* exec factories extension point.
179+
*
180+
* @since 3.23
181+
*/
182+
public static final String EXTENSION_POINT_EXEC_FACTORIES = "execFactories"; //$NON-NLS-1$
183+
173184
/**
174185
* Simple identifier constant (value <code>"logicalStructureTypes"</code>) for the
175186
* logical structure types extension point.
@@ -368,6 +379,13 @@ public class DebugPlugin extends Plugin {
368379
*/
369380
public static final String ATTR_PATH = PI_DEBUG_CORE + ".ATTR_PATH"; //$NON-NLS-1$
370381

382+
/**
383+
* Attribute key for breakpoint grouping types accelerators
384+
*
385+
* @since 3.23
386+
*/
387+
public static final String PREF_SHOW_BREAKPOINT_GROUPBY_TYPE_SHORTCUTS = PI_DEBUG_CORE + ".PREF_FOR_BP_GROUP_TYPE_ACCELERATOR"; //$NON-NLS-1$
388+
371389
/**
372390
* Launch configuration attribute that designates whether or not the
373391
* descendants of the {@link IProcess} associated to a launch of this
@@ -438,6 +456,11 @@ public class DebugPlugin extends Plugin {
438456
*/
439457
private HashMap<String, IConfigurationElement> fProcessFactories = null;
440458

459+
/**
460+
* List of exec factories.
461+
*/
462+
private List<ExecFactoryFacade> execFactories;
463+
441464
/**
442465
* Service tracker for the workspace service
443466
*/
@@ -981,7 +1004,24 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env
9811004
* @since 3.14
9821005
*/
9831006
public static Process exec(String[] cmdLine, File workingDirectory, String[] envp, boolean mergeOutput) throws CoreException {
984-
Process p = null;
1007+
List<ExecFactoryFacade> factories = DebugPlugin.getDefault().getExecFactories();
1008+
Optional<File> directory = shortenWindowsPath(workingDirectory);
1009+
Optional<Map<String, String>> envMap = Optional.ofNullable(envp).map(array -> {
1010+
Map<String, String> map = new LinkedHashMap<>();
1011+
for (String e : array) {
1012+
int index = e.indexOf('=');
1013+
if (index != -1) {
1014+
map.put(e.substring(0, index), e.substring(index + 1));
1015+
}
1016+
}
1017+
return Map.copyOf(map);
1018+
});
1019+
for (ExecFactoryFacade holder : factories) {
1020+
Optional<Process> exec = holder.exec(cmdLine.clone(), directory, envMap, mergeOutput);
1021+
if (exec.isPresent()) {
1022+
return exec.get();
1023+
}
1024+
}
9851025
try {
9861026
// starting with and without merged output could be done with the
9871027
// same process builder approach but since the handling of
@@ -990,25 +1030,18 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env
9901030
// builder to not break existing caller of this method
9911031
if (mergeOutput) {
9921032
ProcessBuilder pb = new ProcessBuilder(cmdLine);
993-
if (workingDirectory != null) {
994-
pb.directory(shortenWindowsPath(workingDirectory));
995-
}
1033+
directory.ifPresent(pb::directory);
9961034
pb.redirectErrorStream(mergeOutput);
997-
if (envp != null) {
1035+
if (envMap.isPresent()) {
9981036
Map<String, String> env = pb.environment();
9991037
env.clear();
1000-
for (String e : envp) {
1001-
int index = e.indexOf('=');
1002-
if (index != -1) {
1003-
env.put(e.substring(0, index), e.substring(index + 1));
1004-
}
1005-
}
1038+
env.putAll(envMap.get());
10061039
}
1007-
p = pb.start();
1008-
} else if (workingDirectory == null) {
1009-
p = Runtime.getRuntime().exec(cmdLine, envp);
1040+
return pb.start();
1041+
} else if (directory.isEmpty()) {
1042+
return Runtime.getRuntime().exec(cmdLine, envp);
10101043
} else {
1011-
p = Runtime.getRuntime().exec(cmdLine, envp, shortenWindowsPath(workingDirectory));
1044+
return Runtime.getRuntime().exec(cmdLine, envp, directory.get());
10121045
}
10131046
} catch (IOException e) {
10141047
Status status = new Status(IStatus.ERROR, getUniqueIdentifier(), ERROR, DebugCoreMessages.DebugPlugin_0, e);
@@ -1021,18 +1054,18 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env
10211054
if (handler != null) {
10221055
Object result = handler.handleStatus(status, null);
10231056
if (result instanceof Boolean resultValue && resultValue) {
1024-
p = exec(cmdLine, null);
1057+
return exec(cmdLine, null);
10251058
}
10261059
}
10271060
}
1028-
return p;
1061+
return null;
10291062
}
10301063

10311064
// https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
10321065
private static final int WINDOWS_MAX_PATH = 258;
10331066

1034-
private static File shortenWindowsPath(File path) {
1035-
if (path.getPath().length() > WINDOWS_MAX_PATH && Platform.OS.isWindows()) {
1067+
private static Optional<File> shortenWindowsPath(File path) {
1068+
if (path != null && path.getPath().length() > WINDOWS_MAX_PATH && Platform.OS.isWindows()) {
10361069
// When spawning new processes on Windows, there is no uniform way
10371070
// to use long working directory paths that exceed the default path
10381071
// length limit, like for example using the raw path prefix '\\?\'
@@ -1042,12 +1075,12 @@ private static File shortenWindowsPath(File path) {
10421075
@SuppressWarnings("restriction")
10431076
String shortPath = org.eclipse.core.internal.filesystem.local.Win32Handler.getShortPathName(path.toString());
10441077
if (shortPath != null) {
1045-
return new File(shortPath);
1078+
return Optional.of(new File(shortPath));
10461079
} else {
10471080
log(Status.warning("Working directory of process to create exceeds Window's MAX_PATH limit and shortening the path failed.")); //$NON-NLS-1$
10481081
}
10491082
}
1050-
return path;
1083+
return Optional.ofNullable(path);
10511084
}
10521085

10531086
/**
@@ -1189,6 +1222,39 @@ private void initializeProcessFactories() {
11891222
}
11901223
}
11911224

1225+
private synchronized List<ExecFactoryFacade> getExecFactories() {
1226+
if (execFactories == null) {
1227+
IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.PI_DEBUG_CORE, EXTENSION_POINT_EXEC_FACTORIES);
1228+
IConfigurationElement[] infos = extensionPoint.getConfigurationElements();
1229+
List<ExecFactoryFacade> list = new ArrayList<>();
1230+
for (IConfigurationElement configurationElement : infos) {
1231+
String clz = configurationElement.getAttribute("class"); //$NON-NLS-1$
1232+
if (clz != null) {
1233+
int priority;
1234+
String attribute = configurationElement.getAttribute("priority"); //$NON-NLS-1$
1235+
if (attribute == null) {
1236+
priority = 0;
1237+
}
1238+
try {
1239+
priority = Integer.parseInt(attribute);
1240+
} catch (NumberFormatException e) {
1241+
log(new Status(IStatus.ERROR, DebugPlugin.PI_DEBUG_CORE, ERROR, MessageFormat.format(DebugCoreMessages.DebugPlugin_invalid_exec_factory, new Object[] {
1242+
configurationElement.getContributor().getName() }), null));
1243+
priority = 0;
1244+
}
1245+
list.add(new ExecFactoryFacade(configurationElement, priority));
1246+
} else {
1247+
String badDefiner = configurationElement.getContributor().getName();
1248+
log(new Status(IStatus.ERROR, DebugPlugin.PI_DEBUG_CORE, ERROR, MessageFormat.format(DebugCoreMessages.DebugPlugin_invalid_exec_factory, new Object[] {
1249+
badDefiner }), null));
1250+
}
1251+
}
1252+
list.sort(Comparator.comparingInt(ExecFactoryFacade::getPriority).reversed());
1253+
execFactories = List.copyOf(list);
1254+
}
1255+
return execFactories;
1256+
}
1257+
11921258
private void invalidStatusHandler(Exception e, String id) {
11931259
log(new Status(IStatus.ERROR, DebugPlugin.PI_DEBUG_CORE, ERROR, MessageFormat.format(DebugCoreMessages.DebugPlugin_5, new Object[] { id }), e));
11941260
}
@@ -1213,14 +1279,41 @@ public int hashCode() {
12131279

12141280
@Override
12151281
public boolean equals(Object obj) {
1216-
if (obj instanceof StatusHandlerKey) {
1217-
StatusHandlerKey s = (StatusHandlerKey)obj;
1282+
if (obj instanceof StatusHandlerKey s) {
12181283
return fCode == s.fCode && fPluginId.equals(s.fPluginId);
12191284
}
12201285
return false;
12211286
}
12221287
}
12231288

1289+
private class ExecFactoryFacade implements ExecFactory {
1290+
1291+
private IConfigurationElement element;
1292+
private int priority;
1293+
1294+
ExecFactoryFacade(IConfigurationElement element, int priority) {
1295+
this.element = element;
1296+
this.priority = priority;
1297+
}
1298+
1299+
public int getPriority() {
1300+
return priority;
1301+
}
1302+
1303+
@Override
1304+
public Optional<Process> exec(String[] cmdLine, Optional<File> workingDirectory, Optional<Map<String, String>> environment, boolean mergeOutput) throws CoreException {
1305+
ExecFactory extension;
1306+
try {
1307+
extension = (ExecFactory) element.createExecutableExtension(IConfigurationElementConstants.CLASS);
1308+
} catch (CoreException e) {
1309+
log(e);
1310+
return Optional.empty();
1311+
}
1312+
return extension.exec(cmdLine, workingDirectory, environment, mergeOutput);
1313+
}
1314+
1315+
}
1316+
12241317
/**
12251318
* Executes runnables after event dispatch is complete.
12261319
*
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Christoph Läubrich 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+
* Christoph Läubrich - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.debug.core;
15+
16+
import java.io.File;
17+
import java.util.Map;
18+
import java.util.Optional;
19+
20+
import org.eclipse.core.runtime.CoreException;
21+
22+
/**
23+
* A {@link ExecFactory} can be used to control how Eclipse forks a new
24+
* {@link Process}.
25+
*
26+
* @since 3.23
27+
*/
28+
public interface ExecFactory {
29+
30+
/**
31+
* Executes the given command with the provided working directory and
32+
* environment
33+
*
34+
* @param cmdLine the commandline to execute
35+
* @param workingDirectory an optional working directory to be used
36+
* otherwise the process factory must use its default
37+
* @param environment the environment to use, if empty the process factory
38+
* must use its defaults
39+
* @param mergeOutput <code>true</code> if standard error and standard out
40+
* should be merged
41+
* @return an {@link Optional} describing the new process created, if an
42+
* empty {@link Optional} is returned it is assumed that this
43+
* factory is not capable of executing the provided command with the
44+
* requested settings
45+
* @throws CoreException if the factory is capable of execution but the
46+
* creation of a process itself has failed
47+
*/
48+
Optional<Process> exec(String[] cmdLine, Optional<File> workingDirectory, Optional<Map<String, String>> environment, boolean mergeOutput) throws CoreException;
49+
50+
}

debug/org.eclipse.debug.core/core/org/eclipse/debug/core/Launch.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -527,10 +527,9 @@ public void disconnect() throws DebugException {
527527
readLock.lock();
528528
try {
529529
for (IProcess process : getProcesses0()) {
530-
if (process instanceof IDisconnect) {
531-
IDisconnect dis = (IDisconnect) process;
532-
if (dis.canDisconnect()) {
533-
dis.disconnect();
530+
if (process instanceof IDisconnect disc) {
531+
if (disc.canDisconnect()) {
532+
disc.disconnect();
534533
}
535534
}
536535
}

debug/org.eclipse.debug.core/core/org/eclipse/debug/core/commands/AbstractDebugCommand.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,7 @@ public boolean contains(ISchedulingRule rule) {
187187

188188
@Override
189189
public boolean isConflicting(ISchedulingRule rule) {
190-
if (rule instanceof SerialPerObjectRule) {
191-
SerialPerObjectRule vup = (SerialPerObjectRule) rule;
190+
if (rule instanceof SerialPerObjectRule vup) {
192191
return fObject == vup.fObject;
193192
}
194193
return false;

debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/RuntimeProcess.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,22 @@ public RuntimeProcess(ILaunch launch, Process process, String name, Map<String,
166166
launch.addProcess(this);
167167
fMonitor.start();
168168
fireCreationEvent();
169+
startStreams();
170+
}
171+
172+
/**
173+
* Called after notification that this runtime process is created to start
174+
* the reading of streams. Must be overridden if a custom
175+
* {@link IStreamsProxy} instance is provided by
176+
* {@link #createStreamsProxy()} that do not extends {@link StreamsProxy}
177+
* and does not start the stream reading in any other mean.
178+
*
179+
* @since 3.23
180+
*/
181+
protected void startStreams() {
182+
if (fStreamsProxy instanceof StreamsProxy impl) {
183+
impl.startMonitoring(fThreadNameSuffix);
184+
}
169185
}
170186

171187
private static String getPidInfo(Process process, ILaunch launch) {
@@ -389,7 +405,7 @@ protected IStreamsProxy createStreamsProxy() {
389405
if (charset == null) {
390406
charset = Platform.getSystemCharset();
391407
}
392-
return new StreamsProxy(getSystemProcess(), charset, fThreadNameSuffix);
408+
return new StreamsProxy(getSystemProcess(), charset);
393409
}
394410

395411
/**

0 commit comments

Comments
 (0)