From c1f0dd4b2cd44ff9056ba61f65119e2b5d9b985d Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Thu, 2 Oct 2025 17:23:28 +0200 Subject: [PATCH 01/56] Add comprehensive Copilot instructions for Eclipse Platform repository --- .github/copilot-instructions.md | 267 ++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000000..b340544d8afd --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,267 @@ +# Eclipse Platform Repository - Copilot Instructions + +## Repository Overview + +This repository contains the core Eclipse Platform components that form the basis for the Eclipse IDE. It is a **large-scale Java/OSGi project** (~120MB, 5,600+ Java files across 38 Maven modules) using **Maven/Tycho** for building Eclipse RCP bundles and features. + +**Key Technologies:** +- Language: Java (JDK 17+, targets JDK 21 in CI) +- Build: Maven 3.9+ with Eclipse Tycho (OSGi/RCP build tooling) +- Architecture: OSGi bundles organized as Eclipse plugins +- Testing: JUnit with Tycho Surefire plugin + +**Main Modules:** +- `runtime/` - Core runtime, jobs, expressions, content types (org.eclipse.core.runtime, org.eclipse.core.jobs) +- `resources/` - Workspace, filesystem, project management (org.eclipse.core.resources, org.eclipse.core.filesystem) +- `debug/` - Debug framework and UI, external tools, launch configurations +- `team/` - Version control framework (CVS examples) +- `ua/` - User assistance: help system, cheatsheets, tips +- `ant/` - Ant integration and UI +- `terminal/` - Terminal view +- `platform/` - SDK packaging + +## Critical Build Information + +**⚠️ IMPORTANT: This repository CANNOT be built in isolation.** It depends on a parent POM (`eclipse-platform-parent`) from the [eclipse.platform.releng.aggregator](https://github.com/eclipse-platform/eclipse.platform.releng.aggregator) repository. + +### Individual Bundle Builds + +Individual bundles CAN be built using the pre-configured profile if you have network access to Eclipse repositories: + +```bash +cd # e.g., runtime/bundles/org.eclipse.core.runtime +mvn clean verify -Pbuild-individual-bundles +``` + +The `-Pbuild-individual-bundles` profile (configured in `.mvn/maven.config`) enables the bundle to fetch the parent POM from https://repo.eclipse.org/content/repositories/eclipse/. + +**Note:** If network access to Eclipse repositories is blocked, individual bundle builds will fail. In such environments, code exploration and analysis can still be performed, but build verification is not possible. + +### Full Platform Build + +For full platform builds, use the aggregator repository which includes this repo as a Git submodule. The CI workflows in this repository delegate to workflows in the aggregator repository. + +### Build Profiles Used in CI + +The Jenkinsfile shows the complete build command: +```bash +mvn clean verify --batch-mode --fail-at-end \ + -Pbree-libs -Papi-check -Pjavadoc \ + -Dmaven.test.failure.ignore=true \ + -Dcompare-version-with-baselines.skip=false \ + -Dmaven.compiler.failOnWarning=false +``` + +Key profiles: +- `-Pbree-libs` - Bundle Runtime Execution Environment libraries +- `-Papi-check` - API baseline comparison (detects breaking changes) +- `-Pjavadoc` - Generate Javadoc + +## Testing + +**Test Organization:** +- Tests are in `/tests/` subdirectories (e.g., `runtime/tests/`, `resources/tests/`) +- Test bundles follow naming: `org.eclipse..tests.` +- Tests use JUnit 4/5 with Tycho Surefire + +**Running Tests:** +```bash +# Run tests for a specific bundle +cd +mvn clean verify -Pbuild-individual-bundles + +# Tests are automatically run during 'mvn verify' +# Test results: target/surefire-reports/TEST-*.xml +``` + +**Important Test Notes:** +- Some tests require graphical display (use Xvnc in CI - see Jenkinsfile) +- Tests in `debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/LocalSuite.java` require user terminal and should NOT run on build machines +- Test failures are allowed in CI (`-Dmaven.test.failure.ignore=true`) + +## Validation & CI Checks + +### GitHub Actions Workflows + +All workflows delegate to the aggregator repository: + +1. **PR Checks** (`.github/workflows/pr-checks.yml`): + - Freeze period verification + - No merge commits check + - Version increment verification (uses PDE API Tools) + +2. **Continuous Integration** (`.github/workflows/ci.yml`): + - Delegates to `mavenBuild.yml` in aggregator + - Runs full build with all profiles + +3. **CodeQL** (`.github/workflows/codeql.yml`): + - Security scanning for Java code + +### Local Validation Steps + +Before committing, verify your changes: + +```bash +# 1. Build the affected bundle +cd +mvn clean verify -Pbuild-individual-bundles + +# 2. Check for API issues (PDE API Tools) +# API baseline checks run automatically with -Papi-check +# Results in: target/apianalysis/*.xml + +# 3. Check for compiler warnings +# Results in: target/compilelogs/*.xml +``` + +### API Tools & Version Management + +**Critical:** Eclipse uses semantic versioning with API tooling enforcement: +- Major version: Breaking API changes +- Minor version: Binary compatible API additions, significant changes +- Service version: Bug fixes (increments: +1 for maintenance, +100 for next release) +- Qualifier: Build timestamp + +**Version Change Rules:** +1. API breaking change → Increment major version, reset minor/service to 0 +2. API addition (binary compatible) → Increment minor version, reset service to 0 +3. Bug fix in maintenance → Increment service by 1 +4. Bug fix in next release → Increment service by 100 + +**PDE API Tools automatically detects API changes and enforces version increments.** + +See `docs/VersionNumbering.md` and `docs/Evolving-Java-based-APIs.md` for complete details. + +## Project Structure + +### Root Files +- `pom.xml` - Main reactor POM (defines modules) +- `Jenkinsfile` - Jenkins CI pipeline configuration +- `.mvn/maven.config` - Default Maven options (includes `-Pbuild-individual-bundles`) +- `.gitignore` - Excludes `target/`, `bin/`, `*.class`, etc. + +### Key Configuration Files + +**Per Bundle:** +- `pom.xml` - Maven coordinates and build config +- `META-INF/MANIFEST.MF` - OSGi bundle manifest (Bundle-SymbolicName, Bundle-Version, dependencies) +- `build.properties` - Tycho/PDE build configuration (source folders, bin.includes) +- `.project` - Eclipse project descriptor +- `.classpath` - Eclipse classpath (typically generated) + +**Coding Standards:** +- `docs/Coding_Conventions.md` - Java coding style (follows Oracle conventions with modifications) +- `docs/Naming_Conventions.md` - Package/class naming rules +- Indent with tabs (4 spaces wide) +- Encoding: UTF-8 (see `.settings/org.eclipse.core.resources.prefs`) + +## Common Pitfalls & Solutions + +### 1. Parent POM Resolution Failure +**Error:** `Non-resolvable parent POM for org.eclipse.platform:eclipse.platform` + +**Solution:** Always use `-Pbuild-individual-bundles` profile when building individual bundles. This profile is pre-configured in `.mvn/maven.config` but may be needed explicitly in some contexts. + +### 2. Missing Dependencies During Build +**Error:** Cannot resolve bundle dependencies + +**Solution:** +- Individual bundles fetch dependencies from Eclipse repositories +- Ensure https://repo.eclipse.org is accessible +- Clean local Maven cache if corrupted: `rm -rf ~/.m2/repository/org/eclipse` + +### 3. Test Failures Requiring Display +**Error:** Tests fail with "No display available" + +**Solution:** +- Tests requiring GUI run automatically on CI (Xvnc configured in Jenkinsfile) +- For local testing, use Xvfb: `xvfb-run mvn verify` +- Or skip tests: `mvn verify -DskipTests` + +### 4. API Tools Errors +**Error:** "API baseline errors found" + +**Solution:** +- Review changes in `target/apianalysis/*.xml` +- If API changed, update bundle version in `META-INF/MANIFEST.MF` +- Follow version increment rules (see docs/VersionNumbering.md) +- For intentional API breaks, update baseline comparison + +### 5. Build Timeouts +Maven operations can take considerable time: +- Clean build of single bundle: 1-3 minutes +- Full platform build (aggregator): 30-60 minutes +- Test execution: Variable, some test suites take 10+ minutes + +**Set adequate timeouts when building (default 120s may not be enough):** +```bash +mvn verify -Pbuild-individual-bundles # May need 180-300 seconds +``` + +## Making Changes + +### Typical Change Workflow + +1. **Locate the Bundle:** + - Runtime/core services → `runtime/bundles/` + - Resource/workspace → `resources/bundles/` + - Debug/launch → `debug/` + - Help/documentation → `ua/` + +2. **Make Code Changes:** + - Edit Java sources in bundle's `src/` directory + - Follow coding conventions (see `docs/Coding_Conventions.md`) + - Add/update Javadoc for public APIs + +3. **Update MANIFEST.MF if needed:** + - Changed API? Update `Bundle-Version` following semantic versioning + - New dependencies? Add to `Require-Bundle` or `Import-Package` + +4. **Build and Test:** + ```bash + cd + mvn clean verify -Pbuild-individual-bundles + ``` + +5. **Verify No API Issues:** + - Check `target/apianalysis/*.xml` for API baseline errors + - Address any version increment requirements + +6. **Commit:** + - Write clear commit message + - Reference issue number if applicable + +## File Locations Reference + +**Documentation:** All in `docs/` +- `docs/Coding_Conventions.md` - Code style +- `docs/API_Central.md` - API guidelines hub +- `docs/VersionNumbering.md` - Version management +- `docs/FAQ/` - 200+ FAQ markdown files + +**Build Configuration:** +- `.mvn/maven.config` - Maven CLI defaults +- `Jenkinsfile` - CI build definition (60 min timeout) +- `.github/workflows/*.yml` - GitHub Actions (all delegate to aggregator) + +**Key Bundle Directories:** +- `runtime/bundles/org.eclipse.core.runtime` - Core Platform Runtime +- `runtime/bundles/org.eclipse.core.jobs` - Jobs and scheduling +- `resources/bundles/org.eclipse.core.resources` - Workspace API +- `resources/bundles/org.eclipse.core.filesystem` - Filesystem abstraction + +## Working Efficiently + +**Trust these instructions first.** This repository has a complex build setup that cannot be fully explored from the repository alone. The information above captures the essential knowledge needed to: +- Understand build requirements and limitations +- Make targeted changes without breaking CI +- Navigate the codebase effectively +- Avoid common build pitfalls + +Only search beyond these instructions if: +- Specific API behavior needs clarification (check `docs/FAQ/`) +- Detailed versioning rules are needed (check `docs/VersionNumbering.md`) +- You need examples of existing code patterns (search Java sources) +- CI is failing with an error not covered here (check Jenkinsfile and workflow YAMLs) + +**When in doubt:** Build at the bundle level with `-Pbuild-individual-bundles` profile and verify tests pass locally before pushing changes. From ead5e72a5980ad7c8d1b1fb8e32c8c2326d6f25f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Oct 2025 09:16:00 +0000 Subject: [PATCH 02/56] Fix IllegalArgumentException with duplicate natures Changed ProjectDescription.hasPrivateChanges() to use HashSet instead of Set.of() to handle duplicate natures gracefully. Set.of() throws IllegalArgumentException on duplicates, but HashSet tolerates them and correctly compares nature sets. Also added test case testDuplicateNatures() to ensure this regression doesn't occur again. --- .../resources/ProjectDescription.java | 3 ++- .../core/tests/resources/NatureTest.java | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectDescription.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectDescription.java index 5a1b5d02f6cc..69c5e4085132 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectDescription.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectDescription.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; @@ -581,7 +582,7 @@ public boolean hasPrivateChanges(ProjectDescription description) { return true; } // has natures changed? - if (!Set.of(natures).equals(Set.of(description.natures))) { + if (!new HashSet<>(Arrays.asList(natures)).equals(new HashSet<>(Arrays.asList(description.natures)))) { return true; } // has buildspec changed? diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/NatureTest.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/NatureTest.java index c5483cd4bc9c..d4c82a80eae4 100644 --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/NatureTest.java +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/NatureTest.java @@ -167,6 +167,30 @@ public void testInvalidRemovals() throws Throwable { assertHasEnabledNature(NATURE_SNOW); } + /** + * Tests that duplicate natures in the project description don't cause + * IllegalArgumentException. This is a regression test for a bug where + * Set.of() was used which throws on duplicates. + */ + @Test + public void testDuplicateNatures() throws Throwable { + createInWorkspace(project); + + // Set initial nature + setNatures(project, new String[] { NATURE_SIMPLE }, false); + assertHasEnabledNature(NATURE_SIMPLE); + + // Try to set natures with a duplicate - this should not throw IllegalArgumentException + // The duplicate should be handled gracefully (deduplication happens automatically) + IProjectDescription desc = project.getDescription(); + desc.setNatureIds(new String[] { NATURE_SIMPLE, NATURE_SIMPLE }); + // This should not throw IllegalArgumentException when hasPrivateChanges is called + project.setDescription(desc, IResource.KEEP_HISTORY, createTestMonitor()); + + // After deduplication, only one instance of the nature should remain + assertHasEnabledNature(NATURE_SIMPLE); + } + @Test public void testNatureLifecyle() throws Throwable { createInWorkspace(project); From 068ce093168ad1c1b6a82b877a890dc94459bf07 Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Sun, 5 Oct 2025 13:41:02 +0200 Subject: [PATCH 03/56] Convert terminal test suites from JUnit3/4 to JUnit5 This commit converts the following terminal test suite classes from JUnit3/4 to JUnit5: - AutomatedTestSuite.java: Converted from JUnit3 TestCase with suite() method to JUnit5 @Suite/@SelectClasses - AutomatedPluginTestSuite.java: Converted from JUnit3 TestCase with suite() method to JUnit5 @Suite/@SelectClasses - terminal.internal.emulator.AllTestSuite.java: Converted from JUnit3 TestCase with suite() method to JUnit5 @Suite/@SelectClasses - terminal.internal.model.AllTestSuite.java: Converted from JUnit3 TestCase with suite() method to JUnit5 @Suite/@SelectClasses - terminal.model.AllTestSuite.java: Converted from JUnit3 TestCase/JUnit4TestAdapter to JUnit5 @Suite/@SelectClasses Updated MANIFEST.MF to include org.junit.platform.suite.api import for JUnit5 suite annotations. All tests (336) continue to pass after the conversion. The migration follows the pattern of replacing: - extends TestCase with plain classes - static Test suite() methods with @Suite and @SelectClasses annotations - suite.addTestSuite() calls with class references in @SelectClasses - JUnit4TestAdapter usage with direct class references The test functionality remains identical, only the test runner framework has been modernized. --- .../META-INF/MANIFEST.MF | 3 +- .../internal/emulator/AllTestSuite.java | 24 ++++------- .../terminal/internal/model/AllTestSuite.java | 42 +++++++------------ .../eclipse/terminal/model/AllTestSuite.java | 27 ++++-------- .../test/AutomatedPluginTestSuite.java | 26 ++++-------- .../terminal/test/AutomatedTestSuite.java | 35 +++++----------- 6 files changed, 52 insertions(+), 105 deletions(-) diff --git a/terminal/tests/org.eclipse.terminal.test/META-INF/MANIFEST.MF b/terminal/tests/org.eclipse.terminal.test/META-INF/MANIFEST.MF index bdd9e0f63443..1b61ffdf8b27 100644 --- a/terminal/tests/org.eclipse.terminal.test/META-INF/MANIFEST.MF +++ b/terminal/tests/org.eclipse.terminal.test/META-INF/MANIFEST.MF @@ -21,5 +21,6 @@ Export-Package: org.eclipse.terminal.internal.connector;x-internal:=true, org.eclipse.terminal.model, org.eclipse.terminal.test Import-Package: org.junit.jupiter.api;version="[5.9.3,6.0.0)", - org.junit.jupiter.api.function;version="[5.9.3,6.0.0)" + org.junit.jupiter.api.function;version="[5.9.3,6.0.0)", + org.junit.platform.suite.api;version="[1.9.3,2.0.0)" Automatic-Module-Name: org.eclipse.terminal.test diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/emulator/AllTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/emulator/AllTestSuite.java index 9b9695cf1a46..cac790ea5fe8 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/emulator/AllTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/emulator/AllTestSuite.java @@ -12,27 +12,17 @@ *******************************************************************************/ package org.eclipse.terminal.internal.emulator; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Terminal emulator test cases. * Runs in emulator package to allow access to default visible items. */ -public class AllTestSuite extends TestCase { - public AllTestSuite() { - super(null); - } - - public AllTestSuite(String name) { - super(name); - } - - public static Test suite() { - TestSuite suite = new TestSuite(AllTestSuite.class.getName()); - suite.addTestSuite(VT100EmulatorBackendTest.class); - return suite; - } +@Suite +@SelectClasses({ // + VT100EmulatorBackendTest.class, // +}) +public class AllTestSuite { } diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/model/AllTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/model/AllTestSuite.java index f2bf7ad9f513..47660269f0a3 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/model/AllTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/model/AllTestSuite.java @@ -12,36 +12,26 @@ *******************************************************************************/ package org.eclipse.terminal.internal.model; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Internal Terminal Model test cases. * Runs in internal model package to allow access to default visible items. */ -public class AllTestSuite extends TestCase { - public AllTestSuite() { - super(null); - } - - public AllTestSuite(String name) { - super(name); - } - - public static Test suite() { - TestSuite suite = new TestSuite(AllTestSuite.class.getName()); - suite.addTestSuite(SnapshotChangesTest.class); - suite.addTestSuite(SynchronizedTerminalTextDataTest.class); - suite.addTestSuite(TerminalTextDataFastScrollTest.class); - suite.addTestSuite(TerminalTextDataFastScrollMaxHeightTest.class); - suite.addTestSuite(TerminalTextDataPerformanceTest.class); - suite.addTestSuite(TerminalTextDataSnapshotTest.class); - suite.addTestSuite(TerminalTextDataSnapshotWindowTest.class); - suite.addTestSuite(TerminalTextDataStoreTest.class); - suite.addTestSuite(TerminalTextDataTest.class); - suite.addTestSuite(TerminalTextDataWindowTest.class); - return suite; - } +@Suite +@SelectClasses({ // + SnapshotChangesTest.class, // + SynchronizedTerminalTextDataTest.class, // + TerminalTextDataFastScrollTest.class, // + TerminalTextDataFastScrollMaxHeightTest.class, // + TerminalTextDataPerformanceTest.class, // + TerminalTextDataSnapshotTest.class, // + TerminalTextDataSnapshotWindowTest.class, // + TerminalTextDataStoreTest.class, // + TerminalTextDataTest.class, // + TerminalTextDataWindowTest.class, // +}) +public class AllTestSuite { } diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/model/AllTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/model/AllTestSuite.java index fa3b9b0a37c2..d1c4b9e68d3b 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/model/AllTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/model/AllTestSuite.java @@ -12,29 +12,18 @@ *******************************************************************************/ package org.eclipse.terminal.model; -import junit.framework.JUnit4TestAdapter; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Public Terminal Model test cases. * Runs in internal model package to allow access to default visible items. */ -public class AllTestSuite extends TestCase { - public AllTestSuite() { - super(null); - } - - public AllTestSuite(String name) { - super(name); - } - - public static Test suite() { - TestSuite suite = new TestSuite(AllTestSuite.class.getName()); - suite.addTest(new JUnit4TestAdapter(TerminalColorUITest.class)); - suite.addTestSuite(StyleTest.class); - return suite; - } +@Suite +@SelectClasses({ // + TerminalColorUITest.class, // + StyleTest.class, // +}) +public class AllTestSuite { } diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedPluginTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedPluginTestSuite.java index ec19cdae2902..537449895c54 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedPluginTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedPluginTestSuite.java @@ -13,27 +13,17 @@ package org.eclipse.terminal.test; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Master Test Suite to run all Terminal plug-in tests. */ -public class AutomatedPluginTestSuite extends TestCase { - /** - * Call each AllTestSuite class from each of the test packages. - */ - public static Test suite() { - TestSuite suite = new TestSuite(AutomatedPluginTestSuite.class.getName()); - //These tests require Eclipse Platform to be up - suite.addTestSuite(org.eclipse.terminal.internal.connector.TerminalConnectorPluginTest.class); - suite.addTestSuite(org.eclipse.terminal.internal.connector.TerminalConnectorFactoryTest.class); - - //These tests must run as plain JUnit because they require access - //to "package" protected methods - //suite.addTest(AutomatedTestSuite.suite()); - return suite; - } +@Suite +@SelectClasses({ // + org.eclipse.terminal.internal.connector.TerminalConnectorPluginTest.class, // + org.eclipse.terminal.internal.connector.TerminalConnectorFactoryTest.class, // +}) +public class AutomatedPluginTestSuite { } diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedTestSuite.java index e5f0ef9a8f77..d07b27e91f62 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedTestSuite.java @@ -12,35 +12,22 @@ *******************************************************************************/ package org.eclipse.terminal.test; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Master test suite to run all terminal unit tests. */ -public class AutomatedTestSuite extends TestCase { +@Suite +@SelectClasses({ // + org.eclipse.terminal.internal.emulator.AllTestSuite.class, // + org.eclipse.terminal.internal.model.AllTestSuite.class, // + org.eclipse.terminal.model.AllTestSuite.class, // + org.eclipse.terminal.internal.connector.TerminalConnectorTest.class, // + org.eclipse.terminal.internal.connector.TerminalToRemoteInjectionOutputStreamTest.class, // +}) +public class AutomatedTestSuite { public static final String PI_TERMINAL_TESTS = "org.eclipse.terminal.test"; //$NON-NLS-1$ - public AutomatedTestSuite() { - super(null); - } - - public AutomatedTestSuite(String name) { - super(name); - } - - /** - * Call each AllTestSuite class from each of the test packages. - */ - public static Test suite() { - TestSuite suite = new TestSuite(AutomatedTestSuite.class.getName()); - suite.addTest(org.eclipse.terminal.internal.emulator.AllTestSuite.suite()); - suite.addTest(org.eclipse.terminal.internal.model.AllTestSuite.suite()); - suite.addTest(org.eclipse.terminal.model.AllTestSuite.suite()); - suite.addTestSuite(org.eclipse.terminal.internal.connector.TerminalConnectorTest.class); - suite.addTestSuite(org.eclipse.terminal.internal.connector.TerminalToRemoteInjectionOutputStreamTest.class); - return suite; - } } From 6c6cd74facef04b0b38faa50bda0df88fd93a0a3 Mon Sep 17 00:00:00 2001 From: Pauline DEVILLE Date: Tue, 23 Sep 2025 17:37:27 +0200 Subject: [PATCH 04/56] GH-2167 Launch Group never terminates when many configurations are disabled The previous patch was not completely fixed the issue. Fix issue https://github.com/eclipse-platform/eclipse.platform/issues/2167 Signed-off-by: Pauline DEVILLE --- .../core/groups/GroupLaunchConfigurationDelegate.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java index f8619288729e..98f83ad818a7 100644 --- a/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java @@ -96,14 +96,10 @@ public void launch(ILaunchConfiguration groupConfig, String mode, final ILaunch SubMonitor progress = SubMonitor.convert(monitor, NLS.bind(DebugCoreMessages.GroupLaunchConfigurationDelegate_Launching, groupConfig.getName()), 1000); List launches = createLaunchElements(groupConfig); - int nbEnabledLaunches = launches.stream().filter(l -> l.enabled).toList().size(); - for (int i = 0; i < launches.size(); ++i) { + List enabledLaunches = launches.stream().filter(l -> l.enabled).toList(); + for (int i = 0; i < enabledLaunches.size(); ++i) { GroupLaunchElement le = launches.get(i); - if (!le.enabled) { - continue; - } - // find launch; if not found, skip (error?) final ILaunchConfiguration conf = findLaunchConfiguration(le.name); if (conf == null) { @@ -128,7 +124,7 @@ public void launch(ILaunchConfiguration groupConfig, String mode, final ILaunch // loop detected. report as appropriate and die. IStatusHandler cycleHandler = DebugPlugin.getDefault().getStatusHandler(GROUP_CYCLE); cycleHandler.handleStatus(GROUP_CYCLE, conf.getName()); - } else if (!launchChild(progress.newChild(1000 / nbEnabledLaunches), group, le, conf, localMode, (i == nbEnabledLaunches - 1))) { + } else if (!launchChild(progress.newChild(1000 / enabledLaunches.size()), group, le, conf, localMode, (i == enabledLaunches.size() - 1))) { break; } From 2119800384bb34d5d2056bfc0c8065091145c16e Mon Sep 17 00:00:00 2001 From: Pauline DEVILLE Date: Mon, 6 Oct 2025 10:25:29 +0200 Subject: [PATCH 05/56] fix iterate over enabled launches Signed-off-by: Pauline DEVILLE --- .../internal/core/groups/GroupLaunchConfigurationDelegate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java index 98f83ad818a7..474eb81acf2a 100644 --- a/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java @@ -98,7 +98,7 @@ public void launch(ILaunchConfiguration groupConfig, String mode, final ILaunch List launches = createLaunchElements(groupConfig); List enabledLaunches = launches.stream().filter(l -> l.enabled).toList(); for (int i = 0; i < enabledLaunches.size(); ++i) { - GroupLaunchElement le = launches.get(i); + GroupLaunchElement le = enabledLaunches.get(i); // find launch; if not found, skip (error?) final ILaunchConfiguration conf = findLaunchConfiguration(le.name); From 89435b060c031ff84232793b7240a7c4fbd7da60 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Thu, 9 Oct 2025 17:18:04 +0200 Subject: [PATCH 06/56] Add version constraints for JUnit 5 dependencies --- .../META-INF/MANIFEST.MF | 6 ++-- .../META-INF/MANIFEST.MF | 4 +-- .../META-INF/MANIFEST.MF | 4 +-- .../META-INF/MANIFEST.MF | 14 +++++----- .../META-INF/MANIFEST.MF | 4 +-- .../META-INF/MANIFEST.MF | 6 ++-- .../META-INF/MANIFEST.MF | 28 +++++++++---------- .../META-INF/MANIFEST.MF | 10 +++---- .../META-INF/MANIFEST.MF | 6 ++-- .../META-INF/MANIFEST.MF | 4 +-- .../META-INF/MANIFEST.MF | 8 +++--- .../META-INF/MANIFEST.MF | 6 ++-- .../META-INF/MANIFEST.MF | 4 +-- ua/org.eclipse.ua.tests/META-INF/MANIFEST.MF | 6 ++-- .../META-INF/MANIFEST.MF | 4 +-- 15 files changed, 57 insertions(+), 57 deletions(-) diff --git a/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF index 94398ae36fad..4ec234830ab9 100644 --- a/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF @@ -17,9 +17,9 @@ Require-Bundle: org.eclipse.ui.ide;resolution:=optional, org.eclipse.ant.core, org.eclipse.core.runtime Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Eclipse-BundleShape: dir diff --git a/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF index 41bfd504e198..cee55d8e8c47 100644 --- a/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF @@ -39,8 +39,8 @@ Require-Bundle: org.eclipse.ui.ide;resolution:=optional, org.eclipse.core.externaltools Import-Package: org.assertj.core.api, org.assertj.core.api.iterable, - org.junit.jupiter.api, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-21 Eclipse-BundleShape: dir diff --git a/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF b/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF index a334a59d1472..3270738e80fb 100644 --- a/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF +++ b/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF @@ -14,7 +14,7 @@ Require-Bundle: org.eclipse.core.resources, org.eclipse.core.tests.resources.saveparticipant2, org.eclipse.core.tests.resources.saveparticipant3, org.eclipse.core.filesystem -Import-Package: org.junit.jupiter.api, - org.junit.jupiter.api.extension +Import-Package: org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-ActivationPolicy: lazy diff --git a/resources/tests/org.eclipse.core.tests.resources/META-INF/MANIFEST.MF b/resources/tests/org.eclipse.core.tests.resources/META-INF/MANIFEST.MF index 794aacbe6513..0af9e7d8aa7b 100644 --- a/resources/tests/org.eclipse.core.tests.resources/META-INF/MANIFEST.MF +++ b/resources/tests/org.eclipse.core.tests.resources/META-INF/MANIFEST.MF @@ -36,13 +36,13 @@ Require-Bundle: org.eclipse.core.resources, org.eclipse.core.runtime, org.eclipse.pde.junit.runtime;bundle-version="3.5.0" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.extension, - org.junit.jupiter.api.function, - org.junit.jupiter.api.io, - org.junit.jupiter.params, - org.junit.jupiter.params.provider, - org.junit.platform.suite.api, + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.io;version="[5.14.0,6.0.0)", + org.junit.jupiter.params;version="[5.14.0,6.0.0)", + org.junit.jupiter.params.provider;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)", org.mockito Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 diff --git a/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF index b70706951444..7c1a7dfa6100 100644 --- a/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF @@ -11,8 +11,8 @@ Require-Bundle: org.eclipse.core.contenttype;bundle-version="3.6", org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.core.contenttype.tests diff --git a/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF index 69e2e7115c2d..c51bd9bd3e1d 100644 --- a/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF @@ -11,9 +11,9 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.100,4.0.0)", org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-17 Eclipse-BundleShape: dir Bundle-ActivationPolicy: lazy diff --git a/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF index 4487952ac0c1..4e5157343377 100644 --- a/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF @@ -14,12 +14,12 @@ Require-Bundle: org.junit, org.eclipse.jdt.junit4.runtime, org.eclipse.jdt.junit5.runtime, org.eclipse.pde.junit.runtime, - junit-platform-launcher, - junit-platform-engine, - junit-jupiter-engine, - junit-vintage-engine, - junit-platform-suite-commons, - junit-platform-suite-engine + junit-platform-launcher;bundle-version="[1.14.0,2.0.0)", + junit-platform-engine;bundle-version="[1.14.0,2.0.0)", + junit-jupiter-engine;bundle-version="[5.14.0,6.0.0)", + junit-vintage-engine;bundle-version="[5.14.0,6.0.0)", + junit-platform-suite-commons;bundle-version="[1.14.0,2.0.0)", + junit-platform-suite-engine;bundle-version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Import-Package: javax.xml.parsers, @@ -31,14 +31,14 @@ Import-Package: javax.xml.parsers, net.bytebuddy, org.apiguardian.api, org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.condition, - org.junit.jupiter.api.extension, - org.junit.jupiter.migrationsupport, - org.junit.jupiter.params, - org.junit.platform.commons, - org.junit.platform.runner, - org.junit.platform.suite.api, + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.condition;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.jupiter.migrationsupport;version="[5.14.0,6.0.0)", + org.junit.jupiter.params;version="[5.14.0,6.0.0)", + org.junit.platform.commons;version="[1.14.0,2.0.0)", + org.junit.platform.runner;version="[1.14.0,2.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)", org.opentest4j, org.w3c.dom, org.xml.sax diff --git a/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF index 31efec75674a..96503cbe97d3 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF @@ -15,11 +15,11 @@ Require-Bundle: org.junit, org.eclipse.core.runtime;bundle-version="3.29.0", org.eclipse.core.tests.harness;bundle-version="3.11.0" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.extension, - org.junit.jupiter.api.function, - org.junit.jupiter.api.io, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.io;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Plugin-Class: org.eclipse.core.tests.runtime.RuntimeTestsPlugin diff --git a/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF b/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF index 0c84b8bf90f3..91933eaaa647 100644 --- a/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF +++ b/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF @@ -16,9 +16,9 @@ Require-Bundle: org.eclipse.compare, org.eclipse.team.ui Import-Package: org.assertj.core.api, org.assertj.core.api.iterable, - org.junit.jupiter.api, - org.junit.jupiter.api.extension, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-Activator: org.eclipse.compare.tests.CompareTestPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName diff --git a/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF b/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF index fa254724b702..03e447a8b6d1 100644 --- a/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF +++ b/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF @@ -7,8 +7,8 @@ Bundle-Vendor: Eclipse.org Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.core.net;bundle-version="[1.0.0,2.0.0)" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Eclipse-BundleShape: dir diff --git a/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF b/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF index ac47aefaab60..c44727e10af3 100644 --- a/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF +++ b/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF @@ -27,10 +27,10 @@ Require-Bundle: org.eclipse.ui.ide;resolution:=optional, org.eclipse.core.filesystem, org.eclipse.compare.tests Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.extension, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Eclipse-BundleShape: dir Bundle-RequiredExecutionEnvironment: JavaSE-17 diff --git a/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF b/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF index 5e5dd4b19dad..4f82fba52f87 100644 --- a/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF @@ -15,6 +15,6 @@ Require-Bundle: org.eclipse.tips.ide;bundle-version="0.1.0", Automatic-Module-Name: org.eclipse.tips.tests Import-Package: com.google.gson;version="[2.8.6,3.0.0)", org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" diff --git a/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF b/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF index d9106e7f84e3..6d473b5603b3 100644 --- a/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF @@ -16,8 +16,8 @@ Bundle-ActivationPolicy: lazy Import-Package: javax.servlet;version="3.1.0", javax.servlet.http;version="3.1.0", org.assertj.core.api, - org.junit.jupiter.api, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Export-Package: org.eclipse.ua.tests.doc, org.eclipse.ua.tests.doc.internal;x-internal:=true, org.eclipse.ua.tests.doc.internal.actions;x-internal:=true, diff --git a/ua/org.eclipse.ua.tests/META-INF/MANIFEST.MF b/ua/org.eclipse.ua.tests/META-INF/MANIFEST.MF index e8cc761f27e0..6764b8072cac 100644 --- a/ua/org.eclipse.ua.tests/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.ua.tests/META-INF/MANIFEST.MF @@ -21,9 +21,9 @@ Import-Package: javax.servlet;version="3.1.0", org.apache.lucene.store;version="[10.0.0,11.0.0)", org.apache.lucene.util;version="[10.0.0,11.0.0)", org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.eclipse.ua.tests, org.eclipse.ua.tests.browser.servlet, diff --git a/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF b/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF index 01bac7f4a0d3..4e02e25eabc3 100644 --- a/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF +++ b/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF @@ -13,5 +13,5 @@ Bundle-Vendor: %providerName Export-Package: org.eclipse.update.configurator.tests, org.eclipse.update.internal.configurator.tests Eclipse-BundleShape: dir -Import-Package: org.junit.jupiter.api, - org.junit.platform.suite.api +Import-Package: org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" From 7ee70e2cf5ba3ecebb0b2ce2d5829d892de5501c Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 9 Oct 2025 16:13:26 +0000 Subject: [PATCH 07/56] Version bump(s) for 4.38 stream --- ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF | 2 +- ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF | 2 +- .../org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF | 2 +- team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF | 2 +- team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF | 2 +- team/tests/org.eclipse.core.tests.net/pom.xml | 2 +- team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF | 2 +- team/tests/org.eclipse.team.tests.core/pom.xml | 2 +- ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF | 2 +- ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF | 2 +- ua/org.eclipse.ua.tests.doc/pom.xml | 2 +- .../org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF index 4ec234830ab9..9e60c66d22b9 100644 --- a/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ant.tests.core; singleton:=true -Bundle-Version: 3.7.600.qualifier +Bundle-Version: 3.7.700.qualifier Bundle-ClassPath: anttestscore.jar Bundle-Activator: org.eclipse.ant.tests.core.testplugin.AntTestPlugin Bundle-Vendor: %providerName diff --git a/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF index cee55d8e8c47..3b147d54a5ae 100644 --- a/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ant.tests.ui; singleton:=true -Bundle-Version: 3.12.200.qualifier +Bundle-Version: 3.12.300.qualifier Bundle-ClassPath: anttestsui.jar Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF b/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF index 3270738e80fb..13d919c08dcf 100644 --- a/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF +++ b/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Automatic-Module-Name: org.eclipse.core.tests.resources.saveparticipant Bundle-Name: Eclipse Core Tests Save Participant Bundle-SymbolicName: org.eclipse.core.tests.resources.saveparticipant; singleton:=true -Bundle-Version: 3.6.100.qualifier +Bundle-Version: 3.6.200.qualifier Bundle-Vendor: Eclipse.org Export-Package: org.eclipse.core.tests.resources.saveparticipant Require-Bundle: org.eclipse.core.resources, diff --git a/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF index 7c1a7dfa6100..ddbb119a28cf 100644 --- a/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.core.contenttype.tests;singleton:=true -Bundle-Version: 1.4.100.qualifier +Bundle-Version: 1.4.200.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: diff --git a/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF index c51bd9bd3e1d..1c9eae3130fb 100644 --- a/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.core.expressions.tests; singleton:=true -Bundle-Version: 3.7.500.qualifier +Bundle-Version: 3.7.600.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: diff --git a/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF b/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF index 91933eaaa647..33ddc5aceee9 100644 --- a/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF +++ b/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.compare.tests;singleton:=true -Bundle-Version: 3.8.800.qualifier +Bundle-Version: 3.8.900.qualifier Require-Bundle: org.eclipse.compare, org.eclipse.jface.text, org.eclipse.jface, diff --git a/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF b/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF index 03e447a8b6d1..323d078a0a8e 100644 --- a/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF +++ b/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Net Tests Plug-in Bundle-SymbolicName: org.eclipse.core.tests.net -Bundle-Version: 1.6.400.qualifier +Bundle-Version: 1.6.500.qualifier Bundle-Vendor: Eclipse.org Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.core.net;bundle-version="[1.0.0,2.0.0)" diff --git a/team/tests/org.eclipse.core.tests.net/pom.xml b/team/tests/org.eclipse.core.tests.net/pom.xml index f26bcba583a5..a1a41798d6d6 100644 --- a/team/tests/org.eclipse.core.tests.net/pom.xml +++ b/team/tests/org.eclipse.core.tests.net/pom.xml @@ -17,7 +17,7 @@ 4.38.0-SNAPSHOT org.eclipse.core.tests.net - 1.6.400-SNAPSHOT + 1.6.500-SNAPSHOT eclipse-test-plugin diff --git a/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF b/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF index c44727e10af3..a191a8cd8730 100644 --- a/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF +++ b/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.team.tests.core; singleton:=true -Bundle-Version: 3.10.500.qualifier +Bundle-Version: 3.10.600.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.team.tests.core, diff --git a/team/tests/org.eclipse.team.tests.core/pom.xml b/team/tests/org.eclipse.team.tests.core/pom.xml index 0ef6677001de..c66911365bcb 100644 --- a/team/tests/org.eclipse.team.tests.core/pom.xml +++ b/team/tests/org.eclipse.team.tests.core/pom.xml @@ -17,7 +17,7 @@ 4.38.0-SNAPSHOT org.eclipse.team.tests.core - 3.10.500-SNAPSHOT + 3.10.600-SNAPSHOT eclipse-test-plugin diff --git a/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF b/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF index 4f82fba52f87..eff594da88ce 100644 --- a/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Tip of the Day Tests Bundle-SymbolicName: org.eclipse.tips.tests -Bundle-Version: 1.2.200.qualifier +Bundle-Version: 1.2.300.qualifier Bundle-Vendor: Eclipse Bundle-RequiredExecutionEnvironment: JavaSE-17 Require-Bundle: org.eclipse.tips.ide;bundle-version="0.1.0", diff --git a/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF b/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF index 6d473b5603b3..dc2a34ad8af1 100644 --- a/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.ua.tests.doc;singleton:=true -Bundle-Version: 1.3.100.qualifier +Bundle-Version: 1.3.200.qualifier Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.equinox.http.registry;bundle-version="1.0.200", diff --git a/ua/org.eclipse.ua.tests.doc/pom.xml b/ua/org.eclipse.ua.tests.doc/pom.xml index b2ae6efb1fc0..cb182068da08 100644 --- a/ua/org.eclipse.ua.tests.doc/pom.xml +++ b/ua/org.eclipse.ua.tests.doc/pom.xml @@ -19,7 +19,7 @@ org.eclipse.platform org.eclipse.ua.tests.doc - 1.3.100-SNAPSHOT + 1.3.200-SNAPSHOT eclipse-test-plugin diff --git a/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF b/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF index 4e02e25eabc3..3bf53c47b42d 100644 --- a/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF +++ b/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.update.configurator.tests Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.update.configurator.tests;singleton:=true -Bundle-Version: 0.2.0.qualifier +Bundle-Version: 0.2.100.qualifier Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.update.configurator From 448120f6e19ebc8daf18ed004f853c0e28b1f599 Mon Sep 17 00:00:00 2001 From: sougandhs Date: Wed, 1 Oct 2025 14:17:26 +0530 Subject: [PATCH 08/56] Update Launch Import/Export icons to standard ones --- .../icons/full/elcl16/export_config.svg | 294 ------------------ .../icons/full/elcl16/export_wiz.svg | 148 +++++++++ .../icons/full/elcl16/import_config.svg | 294 ------------------ .../icons/full/elcl16/import_wiz.svg | 164 ++++++++++ .../debug/internal/ui/DebugPluginImages.java | 4 +- 5 files changed, 314 insertions(+), 590 deletions(-) delete mode 100644 debug/org.eclipse.debug.ui/icons/full/elcl16/export_config.svg create mode 100644 debug/org.eclipse.debug.ui/icons/full/elcl16/export_wiz.svg delete mode 100644 debug/org.eclipse.debug.ui/icons/full/elcl16/import_config.svg create mode 100644 debug/org.eclipse.debug.ui/icons/full/elcl16/import_wiz.svg diff --git a/debug/org.eclipse.debug.ui/icons/full/elcl16/export_config.svg b/debug/org.eclipse.debug.ui/icons/full/elcl16/export_config.svg deleted file mode 100644 index 556f280628f5..000000000000 --- a/debug/org.eclipse.debug.ui/icons/full/elcl16/export_config.svg +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/debug/org.eclipse.debug.ui/icons/full/elcl16/export_wiz.svg b/debug/org.eclipse.debug.ui/icons/full/elcl16/export_wiz.svg new file mode 100644 index 000000000000..fda1ba2d5777 --- /dev/null +++ b/debug/org.eclipse.debug.ui/icons/full/elcl16/export_wiz.svg @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + provider + + + + arrow + + + diff --git a/debug/org.eclipse.debug.ui/icons/full/elcl16/import_config.svg b/debug/org.eclipse.debug.ui/icons/full/elcl16/import_config.svg deleted file mode 100644 index d396f12699f7..000000000000 --- a/debug/org.eclipse.debug.ui/icons/full/elcl16/import_config.svg +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/debug/org.eclipse.debug.ui/icons/full/elcl16/import_wiz.svg b/debug/org.eclipse.debug.ui/icons/full/elcl16/import_wiz.svg new file mode 100644 index 000000000000..9d3384c9107f --- /dev/null +++ b/debug/org.eclipse.debug.ui/icons/full/elcl16/import_wiz.svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + receiver + + + + arrow + + + diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugPluginImages.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugPluginImages.java index c99f8bd660d3..93c3f68c8d30 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugPluginImages.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugPluginImages.java @@ -163,9 +163,9 @@ private static void declareImages() { declareRegistryImage(IInternalDebugUIConstants.IMG_ELCL_RESTART, IInternalDebugUIConstants.IMG_DLCL_RESTART, ELCL + "restart_co.svg"); //$NON-NLS-1$ declareRegistryImage(IInternalDebugUIConstants.IMG_ELCL_EXPORT_CONFIG, - IInternalDebugUIConstants.IMG_DLCL_EXPORT_CONFIG, ELCL + "export_config.svg"); //$NON-NLS-1$ + IInternalDebugUIConstants.IMG_DLCL_EXPORT_CONFIG, ELCL + "export_wiz.svg"); //$NON-NLS-1$ declareRegistryImage(IInternalDebugUIConstants.IMG_ELCL_IMPORT_CONFIG, - IInternalDebugUIConstants.IMG_DLCL_IMPORT_CONFIG, ELCL + "import_config.svg"); //$NON-NLS-1$ + IInternalDebugUIConstants.IMG_DLCL_IMPORT_CONFIG, ELCL + "import_wiz.svg"); //$NON-NLS-1$ //Object declareRegistryImage(IDebugUIConstants.IMG_OBJS_LAUNCH_DEBUG, OBJECT + "ldebug_obj.svg"); //$NON-NLS-1$ From 3bcd4f396bbed3992de118b6578ddb1fc42d3fcb Mon Sep 17 00:00:00 2001 From: Andrey Loskutov Date: Fri, 10 Oct 2025 07:17:54 +0200 Subject: [PATCH 09/56] Touch org.eclipse.terminal.view.ui bundle to reflect compiler changes See https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/issues/3412 --- .../org.eclipse.terminal.view.ui/forceQualifierUpdate.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 terminal/bundles/org.eclipse.terminal.view.ui/forceQualifierUpdate.txt diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/forceQualifierUpdate.txt b/terminal/bundles/org.eclipse.terminal.view.ui/forceQualifierUpdate.txt new file mode 100644 index 000000000000..45a1d524bad6 --- /dev/null +++ b/terminal/bundles/org.eclipse.terminal.view.ui/forceQualifierUpdate.txt @@ -0,0 +1,2 @@ +# To force a version qualifier update add the bug here +https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/issues/3412 \ No newline at end of file From ba9634b30203db694389d9392c3cccdd76d0263b Mon Sep 17 00:00:00 2001 From: sougandhs Date: Wed, 8 Oct 2025 12:03:13 +0530 Subject: [PATCH 10/56] Fix launch not found error This commit fixes launch not found error while switching from modified launch config tab to new launch config tab. Fixes : https://github.com/eclipse-platform/eclipse.platform/issues/2003 --- .../CreateLaunchConfigurationAction.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java index c6195ea70958..cf372252dada 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 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 @@ -61,6 +61,11 @@ protected void performAction() { // Construct a new config of the selected type if (object instanceof ILaunchConfiguration config) { try { + if (!config.exists()) { + ILaunchConfiguration[] launches = DebugPlugin.getDefault().getLaunchManager() + .getLaunchConfigurations(); + config = launches[launches.length - 1]; + } type = config.getType(); } catch (CoreException e) { errorDialog(e); From 75b8bca736833a1e14882b3ec8cbea0ee883e2ca Mon Sep 17 00:00:00 2001 From: sougandhs Date: Thu, 9 Oct 2025 12:30:07 +0530 Subject: [PATCH 11/56] Fix Add to run/debug favorite not showing This commit fixes Add to run/debug favorite not showing in launch contexts and updates labels for launches if its already exists in run/debug config --- .../internal/ui/IDebugHelpContextIds.java | 3 +- .../internal/ui/actions/ActionMessages.java | 1 + .../ui/actions/ActionMessages.properties | 1 + .../ui/actions/AddToFavoritesAction.java | 60 ++++++++++--------- 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java index d72f84adf8a3..c45e64351dc2 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 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 @@ -81,6 +81,7 @@ public interface IDebugHelpContextIds { String DEBUG_TOOLBAR_VIEW_ACTION = PREFIX + "debug_toolbar_view_action_context"; //$NON-NLS-1$ String DEBUG_TOOLBAR_WINDOW_ACTION = PREFIX + "debug_toolbar_window_action_context"; //$NON-NLS-1$ String DEBUG_TOOLBAR_BOTH_ACTION = PREFIX + "debug_toolbar_both_action_context"; //$NON-NLS-1$ + String ADD_LAUNCH_CONFIGURATION_TO_FAV_ACTION = PREFIX + "Add_launch_configuration_to_favorites_action_context"; //$NON-NLS-1$ // Views String DEBUG_VIEW = PREFIX + "debug_view_context"; //$NON-NLS-1$ diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java index 7fbb10a0afde..cba82e7430f3 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java @@ -253,5 +253,6 @@ public class ActionMessages extends NLS { public static String EnableAllBreakpointsAction_1; public static String EnableAllBreakpointsAction_3; public static String BreakpointLabelDialog; + public static String RemoveFromFavoritesAction; } \ No newline at end of file diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties index 72ec51c2cf3f..2e1defe031d1 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties @@ -16,6 +16,7 @@ AddToFavoritesAction_1=Add to {0} &Favorites AddToFavoritesAction_2=Error AddToFavoritesAction_3=Unable to add to favorites. +RemoveFromFavoritesAction=Remove from {0} Favorites ChangeVariableValue_errorDialogMessage=Setting the value failed. ChangeVariableValue_errorDialogTitle=Setting Value diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AddToFavoritesAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AddToFavoritesAction.java index beafb6fdef28..940a0f826a81 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AddToFavoritesAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AddToFavoritesAction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 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 @@ -52,7 +52,8 @@ public class AddToFavoritesAction extends SelectionListenerAction { public AddToFavoritesAction() { super(IInternalDebugCoreConstants.EMPTY_STRING); setEnabled(false); - PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugHelpContextIds.EDIT_LAUNCH_CONFIGURATION_ACTION); + PlatformUI.getWorkbench().getHelpSystem().setHelp(this, + IDebugHelpContextIds.ADD_LAUNCH_CONFIGURATION_TO_FAV_ACTION); } /** @@ -66,29 +67,42 @@ protected boolean updateSelection(IStructuredSelection selection) { if (selection.size() == 1) { Object object = selection.getFirstElement(); ILaunch launch = null; - if (object instanceof IAdaptable) { - launch = ((IAdaptable)object).getAdapter(ILaunch.class); + if (object instanceof IAdaptable iAdaptable) { + launch = iAdaptable.getAdapter(ILaunch.class); } if (launch == null) { - if (object instanceof ILaunch) { - launch = (ILaunch)object; - } else if (object instanceof IDebugElement) { - launch = ((IDebugElement)object).getLaunch(); - } else if (object instanceof IProcess) { - launch = ((IProcess)object).getLaunch(); + if (object instanceof ILaunch iLaunch) { + launch = iLaunch; + } else if (object instanceof IDebugElement iDebugElement) { + launch = iDebugElement.getLaunch(); + } else if (object instanceof IProcess iProcess) { + launch = iProcess.getLaunch(); } } if (launch != null) { ILaunchConfiguration configuration = launch.getLaunchConfiguration(); if (configuration != null) { - ILaunchGroup group= DebugUITools.getLaunchGroup(configuration, getMode()); + ILaunchGroup group = DebugUITools.getLaunchGroup(configuration, launch.getLaunchMode()); if (group == null) { return false; } setGroup(group); setLaunchConfiguration(configuration); setMode(launch.getLaunchMode()); - setText(MessageFormat.format(ActionMessages.AddToFavoritesAction_1, DebugUIPlugin.removeAccelerators(getGroup().getLabel()))); + try { + List favoriteGroups = configuration.getAttribute(IDebugUIConstants.ATTR_FAVORITE_GROUPS, + new ArrayList<>()); + if (favoriteGroups.contains(group.getIdentifier())) { + setText(MessageFormat.format(ActionMessages.RemoveFromFavoritesAction, + fMode.substring(0, 1).toUpperCase() + fMode.substring(1))); + } else { + setText(MessageFormat.format(ActionMessages.AddToFavoritesAction_1, + DebugUIPlugin.removeAccelerators( + fMode.substring(0, 1).toUpperCase() + fMode.substring(1)))); + } + } catch (CoreException e) { + DebugUIPlugin.log(e); + } } } } @@ -101,20 +115,7 @@ protected boolean updateSelection(IStructuredSelection selection) { if (DebugUITools.isPrivate(config)) { return false; } - - if (getGroup() != null) { - try { - List groups = config.getAttribute(IDebugUIConstants.ATTR_FAVORITE_GROUPS, (List) null); - if (groups != null) { - return !groups.contains(getGroup().getIdentifier()); - } - return true; - } catch (CoreException e) { - } - - } - - return false; + return true; } /** @@ -177,7 +178,12 @@ public void run() { if (list == null) { list = new ArrayList<>(); } - list.add(getGroup().getIdentifier()); + String groupIdentifier = getGroup().getIdentifier(); + if (list.contains(groupIdentifier)) { + list.remove(groupIdentifier); + } else { + list.add(groupIdentifier); + } ILaunchConfigurationWorkingCopy copy = getLaunchConfiguration().getWorkingCopy(); copy.setAttribute(IDebugUIConstants.ATTR_FAVORITE_GROUPS, list); copy.doSave(); From 5a5410b0b8e52ac526be898b159c2389002dc232 Mon Sep 17 00:00:00 2001 From: sougandhs Date: Sat, 4 Oct 2025 15:44:07 +0530 Subject: [PATCH 12/56] Add Filter text support in Export Launch Configurations This commit adds a filter text field that allows users to quickly find and select launch configurations without manually expanding all launch types or scrolling through the list. --- .../ExportLaunchConfigurationsWizardPage.java | 40 ++++++++++++++++++- .../launchconfigurations/WizardMessages.java | 3 +- .../WizardMessages.properties | 3 +- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/ExportLaunchConfigurationsWizardPage.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/ExportLaunchConfigurationsWizardPage.java index 49854e787f26..513bb11858ab 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/ExportLaunchConfigurationsWizardPage.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/ExportLaunchConfigurationsWizardPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2017 IBM Corporation and others. + * Copyright (c) 2007, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -52,6 +52,8 @@ import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; @@ -155,12 +157,44 @@ public void createControl(Composite parent) { * @param parent the parent to add the check table viewer to */ protected void createViewer(Composite parent) { + Text filterText = new Text(parent, SWT.SEARCH | SWT.CANCEL); + filterText.setMessage(WizardMessages.ImportLaunchTypeToFilter); + filterText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + ViewerFilter filter = new ViewerFilter() { + @Override + public boolean select(Viewer viewer2, Object parentElement, Object element) { + String search = filterText.getText().toLowerCase(); + if (search.isEmpty()) { + fViewer.collapseAll(); + return true; + } + if (element instanceof ILaunchConfiguration launchConfig) { + return launchConfig.getName().toLowerCase().contains(search); + } + if (element instanceof ILaunchConfigurationType launchConfigType) { + try { + for (ILaunchConfiguration config2 : lm.getLaunchConfigurations(launchConfigType)) { + if (config2.getName().toLowerCase().contains(search)) { + return true; + } + } + } catch (Exception e) { + DebugPlugin.log(e); + return false; + } + return false; + } + return true; + } + }; SWTFactory.createWrapLabel(parent, WizardMessages.ExportLaunchConfigurationsWizardPage_3, 2); Tree tree = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.CHECK); GridData gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 2; tree.setLayoutData(gd); fViewer = new CheckboxTreeViewer(tree); + fViewer.addFilter(filter); + fViewer.setLabelProvider(DebugUITools.newDebugModelPresentation()); fViewer.setComparator(new WorkbenchViewerComparator()); fContentProvider = new ConfigContentProvider(); @@ -206,6 +240,10 @@ public void widgetSelected(SelectionEvent e) { setPageComplete(isComplete()); } }); + filterText.addModifyListener(e -> { + fViewer.refresh(); + fViewer.expandAll(); + }); } /** diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.java index 6d6ab8ded877..06d48d23b3e9 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -46,6 +46,7 @@ public class WizardMessages extends NLS { public static String ImportLaunchConfigurationsWizardPage_5; public static String ImportLaunchConfigurationsWizardPage_6; public static String ImportLaunchConfigurationsWizardPage_7; + public static String ImportLaunchTypeToFilter; static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, WizardMessages.class); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.properties b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.properties index f67406b84d1d..78004647e549 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.properties +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2005, 2008 IBM Corporation and others. +# Copyright (c) 2005, 2025 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -40,3 +40,4 @@ ImportLaunchConfigurationsWizardPage_4=You must select at least one configuratio ImportLaunchConfigurationsWizardPage_5=Import launch configurations from the local file system ImportLaunchConfigurationsWizardPage_6=From &Directory: ImportLaunchConfigurationsWizardPage_7=Brows&e... +ImportLaunchTypeToFilter=Type filter text From 7c2d8b846971788d18ef60b149630315b85cf4f8 Mon Sep 17 00:00:00 2001 From: Jonah Graham Date: Tue, 14 Oct 2025 16:01:01 -0400 Subject: [PATCH 13/56] Update from most org.eclipse.tm.terminal.* features to org.eclipse.terminal The Eclipse Terminal feature replaces a whole set of features that the TM project used to provide. The granularity of the TM project is collapsed into a single feature in Eclipse Terminal. For ISVs that require additional granularity they are advised to provide their own features that lists their requirements --- .../features/org.eclipse.terminal.feature/build.properties | 1 + terminal/features/org.eclipse.terminal.feature/p2.inf | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 terminal/features/org.eclipse.terminal.feature/p2.inf diff --git a/terminal/features/org.eclipse.terminal.feature/build.properties b/terminal/features/org.eclipse.terminal.feature/build.properties index b3a611b5c930..e2bd14c5f3eb 100644 --- a/terminal/features/org.eclipse.terminal.feature/build.properties +++ b/terminal/features/org.eclipse.terminal.feature/build.properties @@ -1,2 +1,3 @@ bin.includes = feature.xml,\ + p2.inf,\ feature.properties diff --git a/terminal/features/org.eclipse.terminal.feature/p2.inf b/terminal/features/org.eclipse.terminal.feature/p2.inf new file mode 100644 index 000000000000..c8ab159caed5 --- /dev/null +++ b/terminal/features/org.eclipse.terminal.feature/p2.inf @@ -0,0 +1,6 @@ + +# The Eclipse Terminal feature replaces a whole set of features that the TM project +# used to provide. The granularity of the TM project is collapsed into a single +# feature in Eclipse Terminal. For ISVs that require additional granularity they +# are advised to provide their own features that lists their requirements +update.matchExp=providedCapabilities.exists(pc | pc.namespace == 'org.eclipse.equinox.p2.iu' && (pc.name == 'org.eclipse.terminal.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.connector.local.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.connector.ssh.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.connector.telnet.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.control.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.view.feature.feature.group')) From 48d731412a67f4e064fcb854b796c51e6e988669 Mon Sep 17 00:00:00 2001 From: sougandhs Date: Tue, 14 Oct 2025 17:23:42 +0530 Subject: [PATCH 14/56] Improved Expression Copy This commit improves Copy Expression by excluding eclipse ui values such as pending, error and disabled --- ...yExpressionsToClipboardActionDelegate.java | 32 +++++++++++++++++-- .../VirtualCopyToClipboardActionDelegate.java | 19 +++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java index 45f039d36982..e85629e6c733 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Bachmann electronic GmbH and others. + * Copyright (c) 2017, 2025 Bachmann electronic GmbH and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,15 +10,17 @@ * * Contributors: * Bachmann electronic GmbH - initial API and implementation + * IBM Corporation - Exclude Expression UI values while copying *******************************************************************************/ package org.eclipse.debug.internal.ui.actions.expressions; +import org.eclipse.debug.internal.core.WatchExpression; +import org.eclipse.debug.internal.ui.DebugUIMessages; import org.eclipse.debug.internal.ui.viewers.model.VirtualCopyToClipboardActionDelegate; public class CopyExpressionsToClipboardActionDelegate extends VirtualCopyToClipboardActionDelegate { private static final String QUOTE = "\""; //$NON-NLS-1$ - @Override protected String trimLabel(String rawLabel) { String label = super.trimLabel(rawLabel); @@ -34,5 +36,31 @@ protected String trimLabel(String rawLabel) { return label; } + @Override + protected String exludeLabels(Object itemData, String label) { + if (itemData instanceof WatchExpression watchExp) { + if (watchExp.isPending() || watchExp.hasErrors()) { + if (label.equals(DebugUIMessages.DefaultLabelProvider_12) + || label.contains(DebugUIMessages.DefaultLabelProvider_13)) { + return null; + } + } + if (!watchExp.isEnabled()) { + if (label.equals(DebugUIMessages.DefaultLabelProvider_15)) { + return null; + } + if (label.contains(DebugUIMessages.DefaultLabelProvider_15)) { + int index = label.lastIndexOf(DebugUIMessages.DefaultLabelProvider_15); + if (index != -1) { + label = label.substring(0, index) + + label.substring(index + DebugUIMessages.DefaultLabelProvider_15.length()); + } + } + } + return label; + } + return label; + } + } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/VirtualCopyToClipboardActionDelegate.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/VirtualCopyToClipboardActionDelegate.java index 1c46d887f36b..990fffb0ade5 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/VirtualCopyToClipboardActionDelegate.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/VirtualCopyToClipboardActionDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 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 @@ -146,7 +146,8 @@ protected void append(VirtualItem item, StringBuilder buffer, int indent) { String[] labels = (String[]) item.getData(VirtualItem.LABEL_KEY); if(labels != null && labels.length > 0) { for (String label : labels) { - String text = trimLabel(label); + String text = exludeLabels(item.getData(), label); + text = trimLabel(text); if (text != null && !text.equals(IInternalDebugCoreConstants.EMPTY_STRING)) { buffer.append(text); } @@ -171,6 +172,19 @@ protected String trimLabel(String label) { return label.trim(); } + /** + * Excludes unwanted labels from the selected item + * + * @param itemData Selected object + * @param label Current label + * @return filtered label or null if label or item is null + */ + protected String exludeLabels(Object itemData, String label) { + if (itemData == null || label == null) { + return null; + } + return label; + } private static class ItemsToCopyVirtualItemValidator implements IVirtualItemValidator { Set fItemsToCopy = Collections.EMPTY_SET; @@ -367,4 +381,5 @@ protected boolean getEnableStateForSelection(IStructuredSelection selection) { public void runWithEvent(IAction action, Event event) { run(action); } + } From 7c9078977494a0d6ea74b82e307871ddd087c9fc Mon Sep 17 00:00:00 2001 From: sougandhs Date: Sun, 19 Oct 2025 12:51:03 +0530 Subject: [PATCH 15/56] Optimise code in Copy Expression Remove redundant return and additional empty string calculation --- .../CopyExpressionsToClipboardActionDelegate.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java index e85629e6c733..f9915d57fbec 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java @@ -49,18 +49,12 @@ protected String exludeLabels(Object itemData, String label) { if (label.equals(DebugUIMessages.DefaultLabelProvider_15)) { return null; } - if (label.contains(DebugUIMessages.DefaultLabelProvider_15)) { - int index = label.lastIndexOf(DebugUIMessages.DefaultLabelProvider_15); - if (index != -1) { - label = label.substring(0, index) - + label.substring(index + DebugUIMessages.DefaultLabelProvider_15.length()); - } + int index = label.lastIndexOf(DebugUIMessages.DefaultLabelProvider_15); + if (index != -1) { + label = label.substring(0, index); } } - return label; } return label; } - - } From 70d775d8d8ab957ac6a891370e673180f2eed602 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 23 Oct 2025 02:43:07 +0000 Subject: [PATCH 16/56] Perform clean code of debug/org.eclipse.debug.core --- .../core/org/eclipse/debug/core/DebugPlugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java index 36c94571fa21..497aba4a8d93 100644 --- a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java @@ -1285,8 +1285,8 @@ public boolean equals(Object obj) { private static class ExecFactoryFacade implements ExecFactory { - private IConfigurationElement element; - private int priority; + private final IConfigurationElement element; + private final int priority; ExecFactoryFacade(IConfigurationElement element, int priority) { this.element = element; From f09677ca9507e1608546440dba5127a29d3caa3b Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Tue, 28 Oct 2025 04:47:46 +0000 Subject: [PATCH 17/56] Perform clean code of ua/org.eclipse.ui.cheatsheets --- .../cheatsheets/composite/views/CompositeCheatSheetPage.java | 1 - 1 file changed, 1 deletion(-) diff --git a/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CompositeCheatSheetPage.java b/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CompositeCheatSheetPage.java index ad0047882a1d..e3218b4e4dcf 100644 --- a/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CompositeCheatSheetPage.java +++ b/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CompositeCheatSheetPage.java @@ -67,7 +67,6 @@ * A page which represents a composite cheat sheet */ -@SuppressWarnings("deprecation") // java.util.Observable since 9; public class CompositeCheatSheetPage extends Page implements ISelectionChangedListener, IMenuContributor { public static final String REVIEW_TAG = "__review__"; //$NON-NLS-1$ From 7fde11324d2c6c095356b09449e2ba399bee6b99 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Tue, 28 Oct 2025 04:57:02 +0000 Subject: [PATCH 18/56] Version bump(s) for 4.38 stream --- ua/org.eclipse.ui.cheatsheets/META-INF/MANIFEST.MF | 2 +- ua/org.eclipse.ui.cheatsheets/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ua/org.eclipse.ui.cheatsheets/META-INF/MANIFEST.MF b/ua/org.eclipse.ui.cheatsheets/META-INF/MANIFEST.MF index 392efbc99d9b..a36e35b45fd0 100644 --- a/ua/org.eclipse.ui.cheatsheets/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.ui.cheatsheets/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %PLUGIN_NAME Bundle-SymbolicName: org.eclipse.ui.cheatsheets; singleton:=true -Bundle-Version: 3.8.700.qualifier +Bundle-Version: 3.8.800.qualifier Bundle-Activator: org.eclipse.ui.internal.cheatsheets.CheatSheetPlugin Bundle-Vendor: %PROVIDER_NAME Bundle-Localization: plugin diff --git a/ua/org.eclipse.ui.cheatsheets/pom.xml b/ua/org.eclipse.ui.cheatsheets/pom.xml index 8608b9cad390..599ff5288805 100644 --- a/ua/org.eclipse.ui.cheatsheets/pom.xml +++ b/ua/org.eclipse.ui.cheatsheets/pom.xml @@ -19,6 +19,6 @@ org.eclipse.platform org.eclipse.ui.cheatsheets - 3.8.700-SNAPSHOT + 3.8.800-SNAPSHOT eclipse-plugin From 8a8f4a2ffbcf64464d1ce1db8af62d19f01f0909 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Tue, 28 Oct 2025 02:33:41 +0000 Subject: [PATCH 19/56] Perform clean code of ant/org.eclipse.ant.launching --- .../org/eclipse/ant/internal/launching/AntLaunchingUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingUtil.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingUtil.java index e1cf4bcd0588..a86b89148c2a 100644 --- a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingUtil.java +++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingUtil.java @@ -345,7 +345,7 @@ public static IFile getFileForLocation(String path, File buildFileParent) { * if unable to migrate * @since 3.0 */ - @SuppressWarnings({ "restriction", "deprecation" }) + @SuppressWarnings({ "deprecation" }) public static void migrateToNewClasspathFormat(ILaunchConfiguration configuration) throws CoreException { String oldClasspath = configuration.getAttribute(AntLaunching.ATTR_ANT_CUSTOM_CLASSPATH, (String) null); String oldAntHome = configuration.getAttribute(AntLaunching.ATTR_ANT_HOME, (String) null); From 018c6675e88989019cc049a6f008a6fe34d9a492 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Tue, 28 Oct 2025 02:41:20 +0000 Subject: [PATCH 20/56] Version bump(s) for 4.38 stream --- ant/org.eclipse.ant.launching/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ant/org.eclipse.ant.launching/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.launching/META-INF/MANIFEST.MF index 9c9a10f1a426..b3c019c61958 100644 --- a/ant/org.eclipse.ant.launching/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.launching/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Localization: plugin Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ant.launching;singleton:=true -Bundle-Version: 1.4.800.qualifier +Bundle-Version: 1.4.900.qualifier Bundle-Activator: org.eclipse.ant.internal.launching.AntLaunching Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.debug.core;bundle-version="[3.12.0,4.0.0)", From 057fa0a5a6b3390b73628ef99a0cf24053398d2f Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 30 Oct 2025 02:39:12 +0000 Subject: [PATCH 21/56] Perform clean code of ant/org.eclipse.ant.ui --- .../ant/internal/ui/datatransfer/AntNewJavaProjectPage.java | 2 +- .../eclipse/ant/internal/ui/preferences/AntClasspathBlock.java | 2 +- .../eclipse/ant/internal/ui/preferences/AntPropertiesBlock.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectPage.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectPage.java index e4ae08edbf6b..ad540ae4db52 100644 --- a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectPage.java +++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectPage.java @@ -270,7 +270,7 @@ private void handleBrowseButtonPressed() { String lastUsedPath = IAntCoreConstants.EMPTY_STRING; FileDialog dialog = new FileDialog(getShell(), SWT.SINGLE | SWT.SHEET); - dialog.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ ; + dialog.setFilterExtensions("*.xml"); //$NON-NLS-1$ ; dialog.setFilterPath(lastUsedPath); String result = dialog.open(); diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java index b95781c15113..ce5a3c79b6cc 100644 --- a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java +++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java @@ -239,7 +239,7 @@ private void addExternalJars() { lastUsedPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString(); } FileDialog dialog = new FileDialog(treeViewer.getControl().getShell(), SWT.MULTI | SWT.SHEET); - dialog.setFilterExtensions(new String[] { "*.jar;*.zip" }); //$NON-NLS-1$ + dialog.setFilterExtensions("*.jar;*.zip"); //$NON-NLS-1$ dialog.setFilterPath(lastUsedPath); String result = dialog.open(); diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesBlock.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesBlock.java index ac7651902005..7e4e667f8eab 100644 --- a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesBlock.java +++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesBlock.java @@ -411,7 +411,7 @@ private void addExternalPropertyFile() { lastUsedPath = IAntCoreConstants.EMPTY_STRING; } FileDialog dialog = new FileDialog(fileTableViewer.getControl().getShell(), SWT.MULTI | SWT.SHEET); - dialog.setFilterExtensions(new String[] { "*.properties", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$ ; + dialog.setFilterExtensions("*.properties", "*.*"); //$NON-NLS-1$ //$NON-NLS-2$ ; dialog.setFilterPath(lastUsedPath); String result = dialog.open(); From 38b1b0c06dc8b950db287796b4db30f6959166d6 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 30 Oct 2025 02:47:27 +0000 Subject: [PATCH 22/56] Version bump(s) for 4.38 stream --- ant/org.eclipse.ant.ui/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ant/org.eclipse.ant.ui/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.ui/META-INF/MANIFEST.MF index 5ba2810b4d3b..c14ad5fe8e83 100644 --- a/ant/org.eclipse.ant.ui/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ant.ui; singleton:=true -Bundle-Version: 3.10.200.qualifier +Bundle-Version: 3.10.300.qualifier Bundle-Activator: org.eclipse.ant.internal.ui.AntUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin From 77724b276109c5f2bff3b4287a9fbc2fcffb7ff6 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 30 Oct 2025 04:26:17 +0000 Subject: [PATCH 23/56] Perform clean code of ua/org.eclipse.ui.cheatsheets --- .../dialogs/CheatSheetCategoryBasedSelectionDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java b/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java index 3248e553511b..2c794fdb104d 100644 --- a/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java +++ b/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java @@ -363,7 +363,7 @@ private class BrowseListener implements SelectionListener { public void widgetSelected(SelectionEvent e) { // Launch a file dialog to select a cheatsheet file FileDialog fileDlg = new FileDialog(getShell()); - fileDlg.setFilterExtensions(new String[]{"*.xml"}); //$NON-NLS-1$ + fileDlg.setFilterExtensions("*.xml"); //$NON-NLS-1$ fileDlg.setText(Messages.SELECTION_DIALOG_FILEPICKER_TITLE); fileDlg.open(); String filename = fileDlg.getFileName(); From 18e228eff1fd4d0fa5ce12390161f6bc448f3567 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 30 Oct 2025 02:59:35 +0000 Subject: [PATCH 24/56] Perform clean code of debug/org.eclipse.debug.ui --- .../importexport/breakpoints/WizardExportBreakpointsPage.java | 2 +- .../importexport/breakpoints/WizardImportBreakpointsPage.java | 2 +- .../browsers/ExternalArchiveSourceContainerBrowser.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardExportBreakpointsPage.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardExportBreakpointsPage.java index a02d5c509130..69779ecf1f85 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardExportBreakpointsPage.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardExportBreakpointsPage.java @@ -144,7 +144,7 @@ protected void handlePathTextModifiedEvent() { */ protected void handleDestinationBrowseButtonPressed() { FileDialog dialog = new FileDialog(getContainer().getShell(), SWT.SAVE | SWT.SHEET); - dialog.setFilterExtensions(new String[]{"*."+IImportExportConstants.EXTENSION}); //$NON-NLS-1$ + dialog.setFilterExtensions("*."+IImportExportConstants.EXTENSION); //$NON-NLS-1$ dialog.setText(ImportExportMessages.WizardExportBreakpoints_0); String file = dialog.open(); if(file != null) { diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardImportBreakpointsPage.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardImportBreakpointsPage.java index a7b4f33eed07..7ee6bdaf28ce 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardImportBreakpointsPage.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardImportBreakpointsPage.java @@ -91,7 +91,7 @@ public void handleEvent(Event event) { */ protected void handleBrowseForFileButtonPressed() { FileDialog dialog = new FileDialog(getContainer().getShell(), SWT.OPEN | SWT.SHEET); - dialog.setFilterExtensions(new String[]{"*."+IImportExportConstants.EXTENSION}); //$NON-NLS-1$ + dialog.setFilterExtensions("*."+IImportExportConstants.EXTENSION); //$NON-NLS-1$ String file = dialog.open(); if(file != null) { fFileNameField.setText(file); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/browsers/ExternalArchiveSourceContainerBrowser.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/browsers/ExternalArchiveSourceContainerBrowser.java index 18d93fc60b92..b742bb66ac03 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/browsers/ExternalArchiveSourceContainerBrowser.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/browsers/ExternalArchiveSourceContainerBrowser.java @@ -42,7 +42,7 @@ public ISourceContainer[] addSourceContainers(Shell shell, ISourceLookupDirector .getDialogSettings(); String rootDir = dialogSettings.get(ROOT_DIR); dialog.setText(SourceLookupUIMessages.ExternalArchiveSourceContainerBrowser_2); - dialog.setFilterExtensions(new String[]{"*.jar;*.zip"}); //$NON-NLS-1$ + dialog.setFilterExtensions("*.jar;*.zip"); //$NON-NLS-1$ if (rootDir != null) { dialog.setFilterPath(rootDir); } From 1ea5d304a2ca9a252a60bba7ea7244db910b26dd Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 30 Oct 2025 03:04:53 +0000 Subject: [PATCH 25/56] Perform clean code of debug/org.eclipse.unittest.ui --- .../org/eclipse/unittest/internal/ui/history/HistoryDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug/org.eclipse.unittest.ui/src/org/eclipse/unittest/internal/ui/history/HistoryDialog.java b/debug/org.eclipse.unittest.ui/src/org/eclipse/unittest/internal/ui/history/HistoryDialog.java index 04cad9da15c0..e5b32c57fa42 100644 --- a/debug/org.eclipse.unittest.ui/src/org/eclipse/unittest/internal/ui/history/HistoryDialog.java +++ b/debug/org.eclipse.unittest.ui/src/org/eclipse/unittest/internal/ui/history/HistoryDialog.java @@ -108,7 +108,7 @@ private void createButtons(Composite res) { Button importButton = new Button(buttons, SWT.PUSH); importButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { FileDialog fileDialog = new FileDialog(getShell()); - fileDialog.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ + fileDialog.setFilterExtensions("*.xml"); //$NON-NLS-1$ fileDialog.setText(Messages.HistoryDialog_selectImport); String path = fileDialog.open(); if (path == null) { From 9001c61e61299f028eeb0b4e4cb9b9f47b5c8eca Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 30 Oct 2025 03:11:26 +0000 Subject: [PATCH 26/56] Version bump(s) for 4.38 stream --- debug/org.eclipse.unittest.ui/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug/org.eclipse.unittest.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.unittest.ui/META-INF/MANIFEST.MF index cc0097a372f8..1175b9d3922c 100644 --- a/debug/org.eclipse.unittest.ui/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.unittest.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.unittest.ui Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.unittest.ui;singleton:=true -Bundle-Version: 1.1.700.qualifier +Bundle-Version: 1.1.800.qualifier Bundle-Activator: org.eclipse.unittest.internal.UnitTestPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName From 879c3bdc9f65ba869f790e82d8bfbfdfd5e373a1 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 30 Oct 2025 03:52:31 +0000 Subject: [PATCH 27/56] Perform clean code of team/bundles/org.eclipse.team.ui --- .../internal/ui/wizards/ExportProjectSetLocationPage.java | 4 ++-- .../team/internal/ui/wizards/ImportProjectSetMainPage.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetLocationPage.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetLocationPage.java index fde06acc8ce1..8586204a6c53 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetLocationPage.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetLocationPage.java @@ -131,8 +131,8 @@ private void createExportToFile(Composite composite) { } FileDialog d = new FileDialog(getShell(), SWT.SAVE); - d.setFilterExtensions(new String[] {"*.psf"}); //$NON-NLS-1$ - d.setFilterNames(new String[] {TeamUIMessages.ExportProjectSetMainPage_Project_Set_Files_3}); + d.setFilterExtensions("*.psf"); //$NON-NLS-1$ + d.setFilterNames(TeamUIMessages.ExportProjectSetMainPage_Project_Set_Files_3); d.setFileName(TeamUIMessages.ExportProjectSetMainPage_default); String fileName = getFileName(); if (fileName != null) { diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java index 3514a030c229..4b88ad83571c 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java @@ -165,8 +165,8 @@ public void widgetSelected(SelectionEvent e) { browseButton.setLayoutData(data); browseButton.addListener(SWT.Selection, event -> { FileDialog d = new FileDialog(getShell()); - d.setFilterExtensions(new String[] {"*.psf", "*"}); //$NON-NLS-1$ //$NON-NLS-2$ - d.setFilterNames(new String[] {TeamUIMessages.ImportProjectSetMainPage_Project_Set_Files_2, TeamUIMessages.ImportProjectSetMainPage_allFiles}); // + d.setFilterExtensions("*.psf", "*"); //$NON-NLS-1$ //$NON-NLS-2$ + d.setFilterNames(TeamUIMessages.ImportProjectSetMainPage_Project_Set_Files_2, TeamUIMessages.ImportProjectSetMainPage_allFiles); // String fileName= getFileName(); if (fileName != null && fileName.length() > 0) { int separator= fileName.lastIndexOf(File.separatorChar); From 874bef9b9692e1d4f341a8c8a06552b6303ac9ae Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Tue, 4 Nov 2025 03:59:07 +0000 Subject: [PATCH 28/56] Perform clean code of team/bundles/org.eclipse.team.core --- .../src/org/eclipse/team/core/IFileTypeInfo.java | 2 ++ .../src/org/eclipse/team/core/IProjectSetSerializer.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java index 5cb19af60f74..4f0b3aa1fee0 100644 --- a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java +++ b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java @@ -28,6 +28,7 @@ public interface IFileTypeInfo { * * @return the file extension */ + @Deprecated public String getExtension(); /** @@ -41,5 +42,6 @@ public interface IFileTypeInfo { * * @return the file type */ + @Deprecated public int getType(); } diff --git a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java index f1c3aeb84cdc..55cda2204b0f 100644 --- a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java +++ b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java @@ -49,6 +49,7 @@ public interface IProjectSetSerializer { * @return String[] an array of serialized reference strings uniquely identifying the projects * @throws TeamException on failures; depends on concrete implementation */ + @Deprecated public String[] asReference(IProject[] providerProjects, Object context, IProgressMonitor monitor) throws TeamException; /** @@ -69,5 +70,6 @@ public interface IProjectSetSerializer { * @return IProject[] an array of projects that were created * @throws TeamException on failures; depends on concrete implementation */ + @Deprecated public IProject[] addToWorkspace(String[] referenceStrings, String filename, Object context, IProgressMonitor monitor) throws TeamException; } From a97efae80eb9145314667eebc824984a291d598a Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Tue, 4 Nov 2025 04:06:20 +0000 Subject: [PATCH 29/56] Version bump(s) for 4.38 stream --- team/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/team/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF b/team/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF index 3c0d9123e70c..e3d5ba8e7367 100644 --- a/team/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF +++ b/team/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.team.core; singleton:=true -Bundle-Version: 3.10.800.qualifier +Bundle-Version: 3.10.900.qualifier Bundle-Activator: org.eclipse.team.internal.core.TeamPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin From fef82c98cd89373f08ad5c3a5014aae8acf52ee4 Mon Sep 17 00:00:00 2001 From: Andrey Loskutov Date: Wed, 5 Nov 2025 08:37:13 +0100 Subject: [PATCH 30/56] Use image from test resources on github instead of using external one Fixes https://github.com/eclipse-platform/eclipse.platform/issues/2246 --- .../src/org/eclipse/tips/core/TipImageURLTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ua/org.eclipse.tips.tests/src/org/eclipse/tips/core/TipImageURLTest.java b/ua/org.eclipse.tips.tests/src/org/eclipse/tips/core/TipImageURLTest.java index ceacbf9483b6..d01ed7b58c1c 100644 --- a/ua/org.eclipse.tips.tests/src/org/eclipse/tips/core/TipImageURLTest.java +++ b/ua/org.eclipse.tips.tests/src/org/eclipse/tips/core/TipImageURLTest.java @@ -25,7 +25,7 @@ public class TipImageURLTest { - private static final String URL = "http://remainsoftware.com/img.png"; + private static final String URL = "https://github.com/eclipse-platform/eclipse.platform/blob/master/ua/org.eclipse.tips.tests/icons/dummy.png"; @org.junit.jupiter.api.Test public void testTipImage() { From 3dfe7e5dcfc38843bb2943c18a7b0525194c5aaf Mon Sep 17 00:00:00 2001 From: Andrey Loskutov Date: Wed, 5 Nov 2025 09:00:45 +0100 Subject: [PATCH 31/56] Use ASCII encoding for test, Eclipse can't start with UTF-16 anymore Fixes https://github.com/eclipse-platform/eclipse.platform/issues/2249 --- .../resources/session/TestWorkspaceEncodingWithJvmArgs.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/session/TestWorkspaceEncodingWithJvmArgs.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/session/TestWorkspaceEncodingWithJvmArgs.java index 46e8259b7721..1edb209e0358 100644 --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/session/TestWorkspaceEncodingWithJvmArgs.java +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/session/TestWorkspaceEncodingWithJvmArgs.java @@ -29,7 +29,7 @@ */ public class TestWorkspaceEncodingWithJvmArgs { - private static final String CHARSET = "UTF-16"; + private static final String CHARSET = "ASCII"; @RegisterExtension SessionTestExtension sessionTestExtension = SessionTestExtension.forPlugin(PI_RESOURCES_TESTS) @@ -38,7 +38,7 @@ public class TestWorkspaceEncodingWithJvmArgs { @BeforeEach @ExecuteInHost public void setUpSession() { - sessionTestExtension.setSystemProperty("file.encoding", "UTF-16"); + sessionTestExtension.setSystemProperty("file.encoding", CHARSET); } @Test From 42c2edb030867a8b2ecab3e06cb8b85ec9052f55 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Sun, 2 Nov 2025 04:44:45 +0000 Subject: [PATCH 32/56] Perform clean code of update/org.eclipse.update.configurator --- .../configurator/ConfiguratorUtils.java | 4 +++ .../configurator/IPlatformConfiguration.java | 26 +++++++++++++++++++ .../IPlatformConfigurationFactory.java | 3 +++ 3 files changed, 33 insertions(+) diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfiguratorUtils.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfiguratorUtils.java index ab903529948b..bb23f728d48d 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfiguratorUtils.java +++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfiguratorUtils.java @@ -44,6 +44,7 @@ public class ConfiguratorUtils { * @return platform configuration used in current instance of platform * @since 3.0 */ + @Deprecated public static IPlatformConfiguration getCurrentPlatformConfiguration() { // acquire factory service first BundleContext context = ConfigurationActivator.getBundleContext(); @@ -69,6 +70,7 @@ public static IPlatformConfiguration getCurrentPlatformConfiguration() { * is specified, an empty configuration object is returned * @return platform configuration used in current instance of platform */ + @Deprecated public static IPlatformConfiguration getPlatformConfiguration(URL url) throws IOException { // acquire factory service first BundleContext context = ConfigurationActivator.getBundleContext(); @@ -95,6 +97,7 @@ public static IPlatformConfiguration getPlatformConfiguration(URL url) throws IO * @param loc location of the platform installation. Used to resolve entries in the save location * @return platform configuration used in current instance of platform */ + @Deprecated public static IPlatformConfiguration getPlatformConfiguration(URL url, URL loc) throws IOException { // acquire factory service first BundleContext context = ConfigurationActivator.getBundleContext(); @@ -115,6 +118,7 @@ public static IPlatformConfiguration getPlatformConfiguration(URL url, URL loc) /** * @return the URL of this eclipse installation */ + @Deprecated public static URL getInstallURL() { return Utils.getInstallURL(); } diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java index 4394c2088404..b298f53891c6 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java +++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java @@ -44,6 +44,7 @@ public interface IPlatformConfiguration { * * @since 2.0 */ + @Deprecated public interface ISiteEntry { /** @@ -167,6 +168,7 @@ public interface ISiteEntry { * * @since 2.0 */ + @Deprecated public interface ISitePolicy { /** @@ -235,6 +237,7 @@ public interface ISitePolicy { * * @since 2.0 */ + @Deprecated public interface IFeatureEntry { /** @@ -315,6 +318,7 @@ public interface IFeatureEntry { * @return created site entry * @since 2.0 */ + @Deprecated public ISiteEntry createSiteEntry(URL url, ISitePolicy policy); /** @@ -327,6 +331,7 @@ public interface IFeatureEntry { * @return created site policy entry * @since 2.0 */ + @Deprecated public ISitePolicy createSitePolicy(int type, String[] list); /** @@ -348,6 +353,7 @@ public interface IFeatureEntry { * @return create feature entry * @since 2.0 */ + @Deprecated public IFeatureEntry createFeatureEntry(String id, String version, String pluginVersion, boolean primary, String application, URL[] root); /** @@ -371,6 +377,7 @@ public interface IFeatureEntry { * @return create feature entry * @since 2.1 */ + @Deprecated public IFeatureEntry createFeatureEntry(String id, String version, String pluginIdentifier, String pluginVersion, boolean primary, String application, URL[] root); /** @@ -380,6 +387,7 @@ public interface IFeatureEntry { * @param entry site entry * @since 2.0 */ + @Deprecated public void configureSite(ISiteEntry entry); /** @@ -392,6 +400,7 @@ public interface IFeatureEntry { * the same URL should be replaced (true) or not (false). * @since 2.0 */ + @Deprecated public void configureSite(ISiteEntry entry, boolean replace); /** @@ -401,6 +410,7 @@ public interface IFeatureEntry { * @param entry site entry * @since 2.0 */ + @Deprecated public void unconfigureSite(ISiteEntry entry); /** @@ -410,6 +420,7 @@ public interface IFeatureEntry { * configured * @since 2.0 */ + @Deprecated public ISiteEntry[] getConfiguredSites(); /** @@ -419,6 +430,7 @@ public interface IFeatureEntry { * @return matching site entry, or null if no match found * @since 2.0 */ + @Deprecated public ISiteEntry findConfiguredSite(URL url); /** @@ -428,6 +440,7 @@ public interface IFeatureEntry { * @param entry feature entry * @since 2.0 */ + @Deprecated public void configureFeatureEntry(IFeatureEntry entry); /** @@ -435,6 +448,7 @@ public interface IFeatureEntry { * @param entry feature entry * @since 2.0 */ + @Deprecated public void unconfigureFeatureEntry(IFeatureEntry entry); /** @@ -443,6 +457,7 @@ public interface IFeatureEntry { * are configured * @since 2.0 */ + @Deprecated public IFeatureEntry[] getConfiguredFeatureEntries(); /** @@ -451,6 +466,7 @@ public interface IFeatureEntry { * @return ferature entry, or null. * @since 2.0 */ + @Deprecated public IFeatureEntry findConfiguredFeatureEntry(String id); /** @@ -460,6 +476,7 @@ public interface IFeatureEntry { * configuration location could not be determined. * @since 2.0 */ + @Deprecated public URL getConfigurationLocation(); /** @@ -470,6 +487,7 @@ public interface IFeatureEntry { * @return configuration change stamp * @since 2.0 */ + @Deprecated public long getChangeStamp(); /** @@ -504,6 +522,7 @@ public interface IFeatureEntry { * @return primary feature identifier, or null if none configured * @since 2.0 */ + @Deprecated public String getPrimaryFeatureIdentifier(); /** @@ -513,6 +532,7 @@ public interface IFeatureEntry { * @return an array of plug-in path elements (full URL entries), or an empty array. * @since 2.0 */ + @Deprecated public URL[] getPluginPath(); /** @@ -549,6 +569,7 @@ public interface IFeatureEntry { * otherwise * @since 2.0 */ + @Deprecated public boolean isUpdateable(); /** @@ -561,6 +582,7 @@ public interface IFeatureEntry { * otherwise * @since 2.0 */ + @Deprecated public boolean isTransient(); /** @@ -574,6 +596,7 @@ public interface IFeatureEntry { * otherwise * @since 2.0 */ + @Deprecated public void isTransient(boolean value); /** @@ -582,12 +605,14 @@ public interface IFeatureEntry { * configuration state, and updates the lists of available plug-ins. * @since 2.0 */ + @Deprecated public void refresh(); /** * Called to save the configuration information * @since 2.0 */ + @Deprecated public void save() throws IOException; /** @@ -597,6 +622,7 @@ public interface IFeatureEntry { * @param url save location. * @since 2.0 */ + @Deprecated public void save(URL url) throws IOException; } diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java index 179470f659ac..39ab8372fa0a 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java +++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java @@ -34,6 +34,7 @@ public interface IPlatformConfigurationFactory { * * @return platform configuration used in current instance of platform */ + @Deprecated public IPlatformConfiguration getCurrentPlatformConfiguration(); /** * Returns a platform configuration object, optionally initialized with previously saved @@ -43,6 +44,7 @@ public interface IPlatformConfigurationFactory { * is specified, an empty configuration object is returned * @return platform configuration used in current instance of platform */ + @Deprecated public IPlatformConfiguration getPlatformConfiguration(URL url) throws IOException; /** @@ -55,5 +57,6 @@ public interface IPlatformConfigurationFactory { * location * @return platform configuration used in current instance of platform */ + @Deprecated public IPlatformConfiguration getPlatformConfiguration(URL url, URL loc) throws IOException; } From 889d003b4ec8f155c3f1ec408642a4c89836de60 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Wed, 5 Nov 2025 03:57:59 +0000 Subject: [PATCH 33/56] Perform clean code of team/bundles/org.eclipse.team.ui --- .../eclipse/team/ui/ISaveableWorkbenchPart.java | 1 + .../org/eclipse/team/ui/PageSaveablePart.java | 16 ++++++++++++++++ .../org/eclipse/team/ui/SaveablePartAdapter.java | 10 ++++++++++ .../org/eclipse/team/ui/SaveablePartDialog.java | 9 +++++++++ .../team/ui/history/HistoryPageSaveablePart.java | 10 ++++++++++ .../ui/synchronize/ParticipantPageDialog.java | 5 +++++ .../synchronize/ParticipantPageSaveablePart.java | 13 +++++++++++++ 7 files changed, 64 insertions(+) diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISaveableWorkbenchPart.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISaveableWorkbenchPart.java index 1beb347a0be6..e56a92fe5d9e 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISaveableWorkbenchPart.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISaveableWorkbenchPart.java @@ -33,5 +33,6 @@ public interface ISaveableWorkbenchPart extends ISaveablePart, IWorkbenchPart { /** * The property id for isDirty. */ + @Deprecated public static final int PROP_DIRTY = ISaveablePart.PROP_DIRTY; } diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java index 68c8e7b24739..fc53db3bfceb 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java @@ -66,6 +66,7 @@ public abstract class PageSaveablePart extends SaveablePartAdapter implements IContentChangeListener{ private final CompareConfiguration cc; + @Deprecated Shell shell; // Tracking of dirty state @@ -87,6 +88,7 @@ public abstract class PageSaveablePart extends SaveablePartAdapter implements IC * @param shell the shell for the part * @param compareConfiguration the compare configuration */ + @Deprecated protected PageSaveablePart(Shell shell, CompareConfiguration compareConfiguration){ this.shell = shell; this.cc = compareConfiguration; @@ -104,11 +106,13 @@ protected PageSaveablePart(Shell shell, CompareConfiguration compareConfiguratio }; } + @Deprecated @Override public boolean isDirty() { return fDirty || fDirtyViewers.size() > 0; } + @Deprecated @Override public void createPartControl(Composite parent) { Composite composite = new Composite(parent, SWT.NULL); @@ -185,6 +189,7 @@ protected Viewer getViewer(Viewer oldViewer, Object input) { * selection listener on the page. * @return the selection provider for the page */ + @Deprecated protected abstract ISelectionProvider getSelectionProvider(); /** @@ -194,6 +199,7 @@ protected Viewer getViewer(Viewer oldViewer, Object input) { * @param toolBarManager the toolbar manager for the page * @return the top-level control for the page */ + @Deprecated protected abstract Control createPage(Composite parent, ToolBarManager toolBarManager); /** @@ -201,6 +207,7 @@ protected Viewer getViewer(Viewer oldViewer, Object input) { * will appear in the header of the pane containing the page. * @param title the page's title */ + @Deprecated protected void setPageDescription(String title) { fEditionPane.setText(title); } @@ -209,6 +216,7 @@ protected void setPageDescription(String title) { * Set the saveable part's dirty state to the given state. * @param dirty the dirty state */ + @Deprecated protected void setDirty(boolean dirty) { boolean confirmSave= true; Object o= cc.getProperty(CompareEditor.CONFIRM_SAVE_PROPERTY); @@ -263,6 +271,7 @@ private void feedInput2(ISelection sel) { * with a progress monitor. * @param input the compare input to be prepared */ + @Deprecated protected void prepareCompareInput(final ICompareInput input) { if (input == null) { return; @@ -295,6 +304,7 @@ protected void prepareCompareInput(final ICompareInput input) { * @param monitor a progress monitor * @throws InvocationTargetException if an error occurs */ + @Deprecated protected abstract void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) throws InvocationTargetException; private void hookContentChangeListener(ICompareInput node) { @@ -313,6 +323,7 @@ private void hookContentChangeListener(ICompareInput node) { * Return the parent shell of this part. * @return the parent shell of this part */ + @Deprecated protected Shell getShell() { return shell; } @@ -321,6 +332,7 @@ protected Shell getShell() { * This method is internal to the framework and should not be called by clients * outside of the framework. */ + @Deprecated protected void setNavigator(ISynchronizePageConfiguration configuration) { configuration.setProperty(SynchronizePageConfiguration.P_NAVIGATOR, new CompareEditorInputNavigator( new Object[] { @@ -366,6 +378,7 @@ private Viewer findContentViewer(Composite parent, Viewer oldViewer, ICompareInp * @param selection the selection * @return a compare input representing the selection */ + @Deprecated protected ICompareInput getCompareInput(ISelection selection) { if (selection != null && selection instanceof IStructuredSelection ss) { if (ss.size() == 1) { @@ -384,6 +397,7 @@ protected ICompareInput getCompareInput(ISelection selection) { * * @param showContentPanes whether to show contents pane */ + @Deprecated public void setShowContentPanes(boolean showContentPanes) { this.showContentPanes = showContentPanes; } @@ -393,6 +407,7 @@ public void setShowContentPanes(boolean showContentPanes) { * * @return the primary control for this part. */ + @Deprecated public Control getControl() { return control; } @@ -413,6 +428,7 @@ private CompareConfiguration getCompareConfiguration() { * @param monitor * a progress monitor */ + @Deprecated @Override public void doSave(IProgressMonitor monitor) { flushViewers(monitor); diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartAdapter.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartAdapter.java index 6b81f98df2fc..72a89457addc 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartAdapter.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartAdapter.java @@ -34,46 +34,56 @@ @Deprecated public abstract class SaveablePartAdapter implements ISaveableWorkbenchPart { + @Deprecated @Override public void doSaveAs() { } + @Deprecated @Override public boolean isSaveAsAllowed() { return false; } + @Deprecated @Override public boolean isSaveOnCloseNeeded() { return false; } + @Deprecated @Override public void addPropertyListener(IPropertyListener listener) { } + @Deprecated @Override public void dispose() { } + @Deprecated @Override public IWorkbenchPartSite getSite() { return null; } + @Deprecated @Override public String getTitleToolTip() { return null; } + @Deprecated @Override public void removePropertyListener(IPropertyListener listener) { } + @Deprecated @Override public void setFocus() { } + @Deprecated @Override public T getAdapter(Class adapter) { return null; diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java index 1d1bef604111..7e344ea94302 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java @@ -55,17 +55,20 @@ public class SaveablePartDialog extends TrayDialog { * @param shell the parent shell or null to create a top level shell. * @param input the part to show in the dialog. */ + @Deprecated public SaveablePartDialog(Shell shell, ISaveableWorkbenchPart input) { super(shell); setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX); this.input = input; } + @Deprecated @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); } + @Deprecated @Override protected Control createDialogArea(Composite parent2) { Composite parent = (Composite) super.createDialogArea(parent2); @@ -77,6 +80,7 @@ protected Control createDialogArea(Composite parent2) { return parent; } + @Deprecated @Override public boolean close() { saveChanges(); @@ -102,10 +106,12 @@ private void saveChanges() { * @return the input to the dialog * @since 3.2 */ + @Deprecated protected ISaveableWorkbenchPart getInput() { return input; } + @Deprecated @Override protected IDialogSettings getDialogBoundsSettings() { IDialogSettings compareSettings = PlatformUI.getDialogSettingsProvider(FrameworkUtil.getBundle(SaveablePartDialog.class)).getDialogSettings(); @@ -122,10 +128,12 @@ protected IDialogSettings getDialogBoundsSettings() { * Set the help content id of this dialog. * @param contextId the help context id */ + @Deprecated public void setHelpContextId(String contextId) { fContextId= contextId; } + @Deprecated @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); @@ -134,6 +142,7 @@ protected void configureShell(Shell newShell) { } } + @Deprecated @Override protected Point getInitialSize() { Point initialSize = super.getInitialSize(); diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/history/HistoryPageSaveablePart.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/history/HistoryPageSaveablePart.java index 46a2a03b7b0c..7c8b61ec1fc0 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/history/HistoryPageSaveablePart.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/history/HistoryPageSaveablePart.java @@ -57,6 +57,7 @@ public class HistoryPageSaveablePart extends PageSaveablePart { * @param object the object * @return whether the object had an {@link IHistoryPageSource} available or not */ + @Deprecated public static boolean showHistoryInDialog(Shell shell, Object object) { IHistoryPageSource pageSource = HistoryPageSource.getHistoryPageSource(object); if (pageSource != null && pageSource.canShowHistoryFor(object)) { @@ -88,26 +89,31 @@ private static boolean isFile(Object object) { * @param pageSource the page source * @param object the object whose history is to be displayed */ + @Deprecated public HistoryPageSaveablePart(Shell shell, CompareConfiguration configuration, IHistoryPageSource pageSource, Object object) { super(shell,configuration); this.pageSource = pageSource; this.object = object; } + @Deprecated @Override public String getTitle() { return historyPage.getName(); } + @Deprecated @Override public Image getTitleImage() { return null; } + @Deprecated @Override public void contentChanged(IContentChangeNotifier source) { } + @Deprecated @Override protected Control createPage(Composite parent, ToolBarManager toolBarManager) { site = new DialogHistoryPageSite(getShell()); @@ -124,11 +130,13 @@ protected Control createPage(Composite parent, ToolBarManager toolBarManager) { return ((Page) historyPage).getControl(); } + @Deprecated @Override protected final ISelectionProvider getSelectionProvider() { return site.getSelectionProvider(); } + @Deprecated @Override protected ICompareInput getCompareInput(ISelection selection) { ICompareInput compareInput = super.getCompareInput(selection); @@ -147,6 +155,7 @@ protected ICompareInput getCompareInput(ISelection selection) { return null; } + @Deprecated @Override protected void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) throws InvocationTargetException { IHistoryCompareAdapter compareAdapter = Adapters.adapt(historyPage, IHistoryCompareAdapter.class); @@ -155,6 +164,7 @@ protected void prepareInput(ICompareInput input, CompareConfiguration configurat } } + @Deprecated @Override public void dispose() { super.dispose(); diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageDialog.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageDialog.java index 306faf803167..0eaa813f723b 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageDialog.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageDialog.java @@ -51,11 +51,13 @@ public class ParticipantPageDialog extends SaveablePartDialog { * @param input the compare input to show in the dialog * @param participant the given participant */ + @Deprecated public ParticipantPageDialog(Shell shell, SaveablePartAdapter input, ISynchronizeParticipant participant) { super(shell, input); this.participant = participant; } + @Deprecated @Override protected Control createDialogArea(Composite parent2) { Composite parent = (Composite) super.createDialogArea(parent2); @@ -67,6 +69,7 @@ protected Control createDialogArea(Composite parent2) { return parent; } + @Deprecated @Override protected void buttonPressed(int buttonId) { if(buttonId == IDialogConstants.OK_ID && isRememberParticipant()) { @@ -97,6 +100,7 @@ private void rememberParticipant() { * * @return the participant showing in this dialog. */ + @Deprecated protected ISynchronizeParticipant getParticipant() { return participant; } @@ -109,6 +113,7 @@ protected ISynchronizeParticipant getParticipant() { * view should be presented to the user * @since 3.2 */ + @Deprecated protected boolean isOfferToRememberParticipant() { return true; } diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageSaveablePart.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageSaveablePart.java index 9ad0603daff6..9e6ef97bf714 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageSaveablePart.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageSaveablePart.java @@ -87,12 +87,14 @@ public class ParticipantPageSaveablePart extends PageSaveablePart implements ICo * @param pageConfiguration the configuration that will be provided to the participant prior to creating the page * @param participant the participant whose page will be displayed in this part */ + @Deprecated public ParticipantPageSaveablePart(Shell shell, CompareConfiguration cc, ISynchronizePageConfiguration pageConfiguration, ISynchronizeParticipant participant) { super(shell,cc); this.participant = participant; this.pageConfiguration = pageConfiguration; } + @Deprecated @Override public void dispose() { if(titleImage != null) { @@ -108,6 +110,7 @@ public void dispose() { super.dispose(); } + @Deprecated @Override public Image getTitleImage() { if(titleImage == null) { @@ -116,11 +119,13 @@ public Image getTitleImage() { return titleImage; } + @Deprecated @Override public String getTitle() { return Utils.shortenText(SynchronizeView.MAX_NAME_LENGTH, participant.getName()); } + @Deprecated @Override public boolean isDirty() { if (participant instanceof ModelSynchronizeParticipant msp) { @@ -132,6 +137,7 @@ public boolean isDirty() { return super.isDirty(); } + @Deprecated @Override public void contentChanged(IContentChangeNotifier source) { try { @@ -145,6 +151,7 @@ public void contentChanged(IContentChangeNotifier source) { } } + @Deprecated @Override public void doSave(IProgressMonitor pm) { // TODO needs to work for models @@ -163,6 +170,7 @@ public void doSave(IProgressMonitor pm) { } } + @Deprecated @Override protected Control createPage(Composite parent, ToolBarManager toolBarManager) { listener = event -> { @@ -194,6 +202,7 @@ protected Control createPage(Composite parent, ToolBarManager toolBarManager) { return page.getControl(); } + @Deprecated @Override protected final ISelectionProvider getSelectionProvider() { return ((ISynchronizePage)page).getViewer(); @@ -234,6 +243,7 @@ private void initializeDiffViewer(Viewer viewer) { * {@inheritDoc} * @since 3.2 */ + @Deprecated @Override protected void prepareInput(final ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) throws InvocationTargetException { monitor.beginTask(TeamUIMessages.SyncInfoCompareInput_3, 100); @@ -302,6 +312,7 @@ private static void commit(IProgressMonitor pm, DiffNode node) throws CoreExcept * * @return Returns the pageConfiguration. */ + @Deprecated public ISynchronizePageConfiguration getPageConfiguration() { return pageConfiguration; } @@ -311,6 +322,7 @@ public ISynchronizePageConfiguration getPageConfiguration() { * * @return Returns the participant. */ + @Deprecated public ISynchronizeParticipant getParticipant() { return participant; } @@ -319,6 +331,7 @@ public ISynchronizeParticipant getParticipant() { * {@inheritDoc} * @since 3.2 */ + @Deprecated @Override protected ICompareInput getCompareInput(ISelection selection) { ICompareInput compareInput = super.getCompareInput(selection); From f3948885a713bf1e1b35b04bbc08e6c5995e6df5 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Wed, 5 Nov 2025 03:47:19 +0000 Subject: [PATCH 34/56] Perform clean code of team/bundles/org.eclipse.compare --- .../compare/EditionSelectionDialog.java | 19 +++++++++++++++++++ .../org/eclipse/compare/IStreamMerger.java | 4 ++++ .../CompareWithOtherResourceAction.java | 2 ++ 3 files changed, 25 insertions(+) diff --git a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/EditionSelectionDialog.java b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/EditionSelectionDialog.java index 9d70bbe589f3..4d7493964405 100644 --- a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/EditionSelectionDialog.java +++ b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/EditionSelectionDialog.java @@ -237,6 +237,7 @@ public int hashCode() { * @param parent if not null the new dialog stays on top of this parent shell * @param bundle ResourceBundle to configure the dialog */ + @Deprecated public EditionSelectionDialog(Shell parent, ResourceBundle bundle) { super(parent, bundle); } @@ -268,6 +269,7 @@ public void setStatusMessage(String message) { * @param contextId the help context id. * @since 3.2 */ + @Deprecated @Override public void setHelpContextId(String contextId) { super.setHelpContextId(contextId); @@ -279,6 +281,7 @@ public void setHelpContextId(String contextId) { * @param titleArgument an optional argument for the edition pane's title * @since 2.0 */ + @Deprecated public void setEditionTitleArgument(String titleArgument) { fTitleArg= titleArgument; } @@ -289,6 +292,7 @@ public void setEditionTitleArgument(String titleArgument) { * @param titleImage an optional image for the edition pane's title * @since 2.0 */ + @Deprecated public void setEditionTitleImage(Image titleImage) { fTitleImage= titleImage; } @@ -305,6 +309,7 @@ public void setEditionTitleImage(Image titleImage) { * it is an ITypedElement returned from IStructureCreator.locate(path, item) * @since 2.0 */ + @Deprecated public ITypedElement selectPreviousEdition(final ITypedElement target, ITypedElement[] inputEditions, Object ppath) { Assert.isNotNull(target); fTargetPair= new Pair(null, target); @@ -380,6 +385,7 @@ public ITypedElement selectPreviousEdition(final ITypedElement target, ITypedEle * if path was null; otherwise * it is an ITypedElement returned from IStructureCreator.locate(path, item) */ + @Deprecated public ITypedElement selectEdition(final ITypedElement target, ITypedElement[] inputEditions, Object ppath) { Assert.isNotNull(target); @@ -544,6 +550,7 @@ private Pair createPair(IStructureCreator sc, Object path, ITypedElement input) * @param hide if true identical entries are hidden; otherwise they are shown. * @since 2.0 */ + @Deprecated public void setHideIdenticalEntries(boolean hide) { fHideIdentical= hide; } @@ -554,6 +561,7 @@ public void setHideIdenticalEntries(boolean hide) { * @param isRight if true target is shown on right hand side. * @since 2.0 */ + @Deprecated public void setTargetIsRight(boolean isRight) { fTargetIsRight= isRight; } @@ -565,6 +573,7 @@ public void setTargetIsRight(boolean isRight) { * @param addMode if true dialog is in 'add' mode. * @since 2.0 */ + @Deprecated public void setAddMode(boolean addMode) { fAddMode= addMode; fMultiSelect= addMode; @@ -577,6 +586,7 @@ public void setAddMode(boolean addMode) { * @param compareMode if true dialog is in 'add' mode. * @since 2.0 */ + @Deprecated public void setCompareMode(boolean compareMode) { fCompareMode= compareMode; fStructureCompare= fCompareMode && !fAddMode; @@ -593,6 +603,7 @@ public void setCompareMode(boolean compareMode) { * * @return the last specified target or a subsection thereof. */ + @Deprecated public ITypedElement getTarget() { return fTargetPair.getItem(); } @@ -604,6 +615,7 @@ public ITypedElement getTarget() { * @return the selected editions as an array. * @since 2.1 */ + @Deprecated public ITypedElement[] getSelection() { ArrayList result= new ArrayList<>(); if (fMemberSelection != null) { @@ -635,6 +647,7 @@ public ITypedElement[] getSelection() { * @param item if a path has been specified in selectEdition a sub element of the given target; otherwise the same as target * @return a label the target side of a compare viewer */ + @Deprecated protected String getTargetLabel(ITypedElement target, ITypedElement item) { String format= null; if (target instanceof ResourceNode) { @@ -680,6 +693,7 @@ private boolean hasVariable(String string) { * @param item if a path has been specified in selectEdition a sub element of the given selectedEdition; otherwise the same as selectedEdition * @return a label for the edition side of a compare viewer */ + @Deprecated protected String getEditionLabel(ITypedElement selectedEdition, ITypedElement item) { String format= null; if (selectedEdition instanceof ResourceNode) { @@ -721,6 +735,7 @@ protected String getEditionLabel(ITypedElement selectedEdition, ITypedElement it * @return a label of a node in the edition tree viewer * @since 2.0 */ + @Deprecated protected String getShortEditionLabel(ITypedElement edition, ITypedElement item, Date date) { String format= null; if (edition instanceof ResourceNode) { @@ -752,6 +767,7 @@ protected String getShortEditionLabel(ITypedElement edition, ITypedElement item, * @return a label the edition side of a compare viewer * @since 2.0 */ + @Deprecated protected Image getEditionImage(ITypedElement selectedEdition, ITypedElement item) { if (selectedEdition instanceof ResourceNode) { return selectedEdition.getImage(); @@ -769,6 +785,7 @@ protected Image getEditionImage(ITypedElement selectedEdition, ITypedElement ite return null; } + @Deprecated @Override protected synchronized Control createDialogArea(Composite parent2) { @@ -905,6 +922,7 @@ protected Viewer getViewer(Viewer oldViewer, Object input) { return parent; } + @Deprecated @Override protected void createButtonsForButtonBar(Composite parent) { String buttonLabel= Utilities.getString(fBundle, "buttonLabel", IDialogConstants.OK_LABEL); //$NON-NLS-1$ @@ -923,6 +941,7 @@ protected void createButtonsForButtonBar(Composite parent) { * Overidden to disable dismiss on double click in compare mode. * @since 2.0 */ + @Deprecated @Override protected void okPressed() { if (fCompareMode) { diff --git a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/IStreamMerger.java b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/IStreamMerger.java index 6c2c622ea0f8..70fa80fcad36 100644 --- a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/IStreamMerger.java +++ b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/IStreamMerger.java @@ -35,16 +35,19 @@ public interface IStreamMerger { /** * Indicates the successful completion of the merge operation (value IStatus.OK) */ + @Deprecated public static final int OK= IStatus.OK; /** * Indicates that a change conflict prevented the merge from successful completion (value 1) */ + @Deprecated public static final int CONFLICT= 1; /** * Status code describing an internal error (value 2) */ + @Deprecated public static final int INTERNAL_ERROR= 2; /** @@ -65,6 +68,7 @@ public interface IStreamMerger { * @param monitor reports progress of the merge operation * @return returns the completion status of the operation */ + @Deprecated IStatus merge(OutputStream output, String outputEncoding, InputStream ancestor, String ancestorEncoding, InputStream target, String targetEncoding, diff --git a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java index a523d7d5611d..28d442a49433 100644 --- a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java +++ b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java @@ -26,6 +26,7 @@ @Deprecated public class CompareWithOtherResourceAction extends CompareAction { + @Deprecated @Override public void run(ISelection selection) { // Show CompareWithOtherResourceDialog which return resources to compare @@ -34,6 +35,7 @@ public void run(ISelection selection) { super.run(selection); } + @Deprecated @Override protected boolean isEnabled(ISelection selection) { int selectionSize = 0; From a20bea2c69b28e1c666dcf6c4e3a7589fe5b6266 Mon Sep 17 00:00:00 2001 From: Andrey Loskutov Date: Wed, 29 Oct 2025 18:39:18 +0100 Subject: [PATCH 35/56] UnifiedTree.isRecursiveLink() links check may silently ignore some links - Main fix: the child path created from the link should use `realParentPath` to avoid silent `NoSuchFileException`'s if the constructed link does not match actual (fully resolved) file system state of the local file we are checking. Original code run into (silent) exceptions and because of that was not able to detect some of possible recursive links. - Removed pattern checking for "../X" because backwards links can also be created with absolute paths, as seen in `Bug_185247_recursiveLinks.test5_linkParentDirectoyTwiceWithAbsolutePath(boolean)` - Added regression test `SymlinkResourceTest.testGithubBug2220`. - Added `UnifiedTree` methods to set/read `disable_advanced_recursive_link_checks` flag in tests so we can test both variants of link checking code. - Updated existing tests to test both advanced / simple link checks (where possible): `SymlinkResourceTest`, `Bug_185247_recursiveLinks` & `Bug_185247_LinuxTests` - Improved `WorkspaceResetExtension` to properly report test names (it only reported `false` or `true` for parametrized tests). Fixes https://github.com/eclipse-platform/eclipse.platform/issues/2220 --- .../core/internal/localstore/UnifiedTree.java | 62 +++++-- .../localstore/SymlinkResourceTest.java | 175 ++++++++++++++---- .../regression/Bug_185247_LinuxTests.java | 55 +++--- .../regression/Bug_185247_recursiveLinks.java | 75 ++++---- .../util/WorkspaceResetExtension.java | 14 +- 5 files changed, 271 insertions(+), 110 deletions(-) diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTree.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTree.java index c610492bd69e..5881c1538423 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTree.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTree.java @@ -438,9 +438,6 @@ private static class PatternHolder { //Pattern: A UNIX or Windows relative path that just points backward static final Pattern TRIVIAL_SYMLINK_PATTERN = Pattern.compile( // Platform.OS.isWindows() ? "\\.[.\\\\]*" : "\\.[./]*"); //$NON-NLS-1$//$NON-NLS-2$ - - static final Pattern REPEATING_BACKWARDS_PATTERN = Pattern.compile( // - Platform.OS.isWindows() ? "(\\.\\.\\\\)+.*" : "(\\.\\./)+.*"); //$NON-NLS-1$//$NON-NLS-2$ } /** @@ -522,20 +519,10 @@ private boolean isRecursiveLink(IFileStore parentStore, IFileInfo localInfo) { Path realParentPath = parent.toRealPath(); if (disable_advanced_recursive_link_checks) { // Multiple ../ backwards links can go outside the project tree - if (linkTarget != null && PatternHolder.REPEATING_BACKWARDS_PATTERN.matcher(linkTarget).matches()) { - Path targetPath = parent.resolve(linkTarget).normalize(); - - // Recursive if literal target points to the literal parent of this tree - if (parent.normalize().startsWith(targetPath)) { + if (linkTarget != null) { + if (isRecursiveBackwardsLink(realParentPath, linkTarget)) { return true; } - - // Recursive if resolved target points to the resolved parent of this tree - Path realTargetPath = targetPath.toRealPath(); - if (realParentPath.startsWith(realTargetPath)) { - return true; - } - // If link is outside the project tree, consider as non recursive // The link still can create recursion in the tree, but we can't detect it here. } @@ -573,6 +560,51 @@ private boolean isRecursiveLink(IFileStore parentStore, IFileInfo localInfo) { return false; } + /** + * @param realParentPath real parent path object obtained as a result + * of @code{Path.toRealPath()} + * @param linkTarget the link target path as a string, may be relative or + * absolute + * @return true if the given target points backwards recursively to the given + * parent path + * @throws IOException + */ + private static boolean isRecursiveBackwardsLink(Path realParentPath, String linkTarget) + throws IOException { + // Cheap test first: literal target points to the literal parent + Path normalizedLink = realParentPath.resolve(linkTarget).normalize(); + if (realParentPath.startsWith(normalizedLink)) { + return true; + } + // Next check costs more time because it does real IO when resolving paths + Path realTarget = normalizedLink.toRealPath(); + if (realParentPath.startsWith(realTarget)) { + return true; + } + return false; + } + + /** + * Disable or enable advanced recursive link checks. Advanced link checks may + * hide valid directories in some cases, see bug 537449. + * + * @param enable true to enable advanced recursive link checks, + * false to disable them. + */ + public static void enableAdvancedRecursiveLinkChecks(boolean enable) { + disable_advanced_recursive_link_checks = !enable; + } + + /** + * Returns whether advanced recursive link checks are enabled. + * + * @return true if advanced recursive link checks are enabled, + * false otherwise. + */ + public static boolean isAdvancedRecursiveLinkChecksEnabled() { + return !disable_advanced_recursive_link_checks; + } + protected boolean isValidLevel(int currentLevel, int depth) { return switch (depth) { case IResource.DEPTH_INFINITE -> true; diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/localstore/SymlinkResourceTest.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/localstore/SymlinkResourceTest.java index 7f7310fb29f1..d121db58b7a8 100644 --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/localstore/SymlinkResourceTest.java +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/localstore/SymlinkResourceTest.java @@ -21,28 +21,33 @@ import static org.eclipse.core.tests.resources.ResourceTestUtil.createInWorkspace; import static org.eclipse.core.tests.resources.ResourceTestUtil.createTestMonitor; import static org.eclipse.core.tests.resources.ResourceTestUtil.waitForRefresh; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.internal.localstore.UnifiedTree; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; -import org.eclipse.core.tests.resources.WorkspaceTestRule; -import org.junit.Rule; -import org.junit.Test; - +import org.eclipse.core.runtime.Platform.OS; +import org.eclipse.core.tests.resources.util.WorkspaceResetExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@ExtendWith(WorkspaceResetExtension.class) public class SymlinkResourceTest { - @Rule - public WorkspaceTestRule workspaceRule = new WorkspaceTestRule(); - private void mkLink(IFileStore dir, String src, String tgt, boolean isDir) throws CoreException, IOException { createSymLink(dir.toLocalFile(EFS.NONE, createTestMonitor()), src, tgt, isDir); } @@ -70,6 +75,88 @@ protected void createBug358830Structure(IFileStore rootDir) throws CoreException mkLink(folderA, "link", IPath.fromOSString("../").toOSString(), true); } + /** + * Test a case of both recursive and non recursive symbolic links that uncovered + * issue described in GitHub bug + * 2220. + * + *
{@code
+	 *      /A/B -> /X/Y/Z  	(B is symbolic link as precondition)
+	 *      /A/B/C/D -> ../../D (non-recursive)
+	 *      /A/B/C/E -> ../../Z (recursive)
+	 * }
+ * + * The starting path /A/B/C is already based on link. The real path of start is + * /X/Y/Z/C so ../../Z points (recursive) to /X/Y/Z. /X/Y/D and /X/Y/Z is what + * we expect to resolve but we fail in both cases with NoSuchFileException. + */ + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void testGithubBug2220(boolean useAdvancedLinkCheck) throws Exception { + assumeTrue(canCreateSymLinks(), "only relevant for platforms supporting symbolic links"); + assumeTrue(!OS.isWindows(), "Windows file system handles recursive links differently"); + final boolean originalValue = UnifiedTree.isAdvancedRecursiveLinkChecksEnabled(); + try { + UnifiedTree.enableAdvancedRecursiveLinkChecks(useAdvancedLinkCheck); + IProject project = getWorkspace().getRoot().getProject("testGithubBug2220"); + createInWorkspace(project); + + /* Re-use projects which are cleaned up automatically */ + getWorkspace().run((IWorkspaceRunnable) monitor -> { + /* delete open project because we must re-open with BACKGROUND_REFRESH */ + project.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, createTestMonitor()); + project.create(null); + try { + createGithubBug2220Structure(EFS.getStore(project.getLocationURI())); + } catch (IOException e) { + throw new IllegalStateException("unexpected IOException occurred", e); + } + // Bug only happens with BACKGROUND_REFRESH. + project.open(IResource.BACKGROUND_REFRESH, createTestMonitor()); + }, null); + + // wait for BACKGROUND_REFRESH to complete. + waitForRefresh(); + project.accept(new IResourceVisitor() { + int resourceCount = 0; + + @Override + public boolean visit(IResource resource) { + resourceCount++; + // We have 1 root + .settings + prefs + + .project + 10 elements --> 14 elements + // to visit at most + System.out.println(resourceCount + " visited: " + resource.getFullPath()); + assertTrue(resourceCount <= 15, "Expected max 15 elements to visit, got: " + resourceCount); + return true; + } + }); + } finally { + UnifiedTree.enableAdvancedRecursiveLinkChecks(originalValue); + } + } + + /** + *
{@code
+	 *      /A/B -> /X/Y/Z  	(B is symbolic link as precondition)
+	 *      /A/B/C/D -> ../../D (non-recursive)
+	 *      /A/B/C/E -> ../../Z (recursive)
+	 * }
+ * + * The starting path /A/B/C is already based on link. The real path of start is + * /X/Y/Z/C so ../../Z points (recursive) to /X/Y/Z. + */ + protected void createGithubBug2220Structure(IFileStore rootDir) throws CoreException, IOException { + Path root = rootDir.toLocalFile(EFS.NONE, createTestMonitor()).toPath(); + Files.createDirectories(root.resolve("A")); + Files.createDirectories(root.resolve("X/Y/Z")); + Files.createDirectories(root.resolve("X/Y/D")); + Files.createSymbolicLink(root.resolve("A/B"), root.resolve("X/Y/Z")); + Files.createDirectories(root.resolve("A/B/C")); + Files.createSymbolicLink(root.resolve("A/B/C/D"), Paths.get("../../D")); + Files.createSymbolicLink(root.resolve("A/B/C/E"), Paths.get("../../Z")); + } + /** * Test a very specific case of mutually recursive symbolic links: *
 {@code
@@ -85,7 +172,7 @@ protected void createBug358830Structure(IFileStore rootDir) throws CoreException
 	 */
 	@Test
 	public void testBug232426() throws Exception {
-		assumeTrue("only relevant for platforms supporting symbolic links", canCreateSymLinks());
+		assumeTrue(canCreateSymLinks(), "only relevant for platforms supporting symbolic links");
 
 		IProject project = getWorkspace().getRoot().getProject("Project");
 		createInWorkspace(project);
@@ -118,36 +205,42 @@ public boolean visit(IResource resource) {
 		});
 	}
 
-	@Test
-	public void testBug358830() throws Exception {
-		assumeTrue("only relevant for platforms supporting symbolic links", canCreateSymLinks());
-
-		IProject project = getWorkspace().getRoot().getProject("Project");
-		createInWorkspace(project);
-		/* Re-use projects which are cleaned up automatically */
-		getWorkspace().run((IWorkspaceRunnable) monitor -> {
-			/* delete open project because we must re-open with BACKGROUND_REFRESH */
-			project.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, createTestMonitor());
-			project.create(null);
-			try {
-				createBug358830Structure(EFS.getStore(project.getLocationURI()));
-			} catch (IOException e) {
-				throw new IllegalStateException("unexpected IOException occurred", e);
-			}
-			project.open(IResource.BACKGROUND_REFRESH, createTestMonitor());
-		}, null);
-
-		//wait for BACKGROUND_REFRESH to complete.
-		waitForRefresh();
-		final int resourceCount[] = new int[] {0};
-		project.accept(resource -> {
-			resourceCount[0]++;
-			return true;
-		});
-		// We have 1 root + 1 folder + 1 file (.project)
-		// + .settings / resources prefs
-		// --> 5 elements to visit
-		assertEquals(5, resourceCount[0]);
+	@ParameterizedTest
+	@ValueSource(booleans = { false, true })
+	public void testBug358830(boolean useAdvancedLinkCheck) throws Exception {
+		assumeTrue(canCreateSymLinks(), "only relevant for platforms supporting symbolic links");
+		final boolean originalValue = UnifiedTree.isAdvancedRecursiveLinkChecksEnabled();
+		try {
+			UnifiedTree.enableAdvancedRecursiveLinkChecks(useAdvancedLinkCheck);
+			IProject project = getWorkspace().getRoot().getProject("Project");
+			createInWorkspace(project);
+			/* Re-use projects which are cleaned up automatically */
+			getWorkspace().run((IWorkspaceRunnable) monitor -> {
+				/* delete open project because we must re-open with BACKGROUND_REFRESH */
+				project.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, createTestMonitor());
+				project.create(null);
+				try {
+					createBug358830Structure(EFS.getStore(project.getLocationURI()));
+				} catch (IOException e) {
+					throw new IllegalStateException("unexpected IOException occurred", e);
+				}
+				project.open(IResource.BACKGROUND_REFRESH, createTestMonitor());
+			}, null);
+
+			// wait for BACKGROUND_REFRESH to complete.
+			waitForRefresh();
+			final int resourceCount[] = new int[] { 0 };
+			project.accept(resource -> {
+				resourceCount[0]++;
+				return true;
+			});
+			// We have 1 root + 1 folder + 1 file (.project)
+			// + .settings / resources prefs
+			// --> 5 elements to visit
+			assertEquals(5, resourceCount[0]);
+		} finally {
+			UnifiedTree.enableAdvancedRecursiveLinkChecks(originalValue);
+		}
 	}
 
 }
diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_LinuxTests.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_LinuxTests.java
index 274fe6913c91..c4dce8635333 100644
--- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_LinuxTests.java
+++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_LinuxTests.java
@@ -11,10 +11,10 @@
 package org.eclipse.core.tests.resources.regression;
 
 import static org.eclipse.core.tests.resources.ResourceTestUtil.createTestMonitor;
-import static org.junit.Assume.assumeTrue;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 import java.io.File;
 import java.io.IOException;
@@ -26,6 +26,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import org.eclipse.core.internal.localstore.UnifiedTree;
 import org.eclipse.core.internal.resources.ProjectDescription;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
@@ -38,10 +39,11 @@
 import org.eclipse.core.runtime.URIUtil;
 import org.eclipse.core.tests.resources.util.WorkspaceResetExtension;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 /**
  * Test cases for symbolic links in projects.
@@ -56,7 +58,7 @@ public class Bug_185247_LinuxTests {
 
 	@BeforeEach
 	public void setUp(TestInfo testInfo) throws Exception {
-		assumeTrue("only relevant on Linux", OS.isLinux());
+		assumeTrue(OS.isLinux(), "only relevant on Linux");
 
 		testMethodName = testInfo.getTestMethod().get().getName();
 		IPath randomLocation = IPath.fromPath(tempDirectory);
@@ -74,34 +76,45 @@ private void extractTestCasesArchive(IPath outputLocation) throws Exception {
 		unzip(archive, outputLocation.toFile());
 	}
 
-	@Test
-	public void test1_trivial() throws Exception {
-		runProjectTestCase();
+	@ParameterizedTest
+	@ValueSource(booleans = { false, true })
+	public void test1_trivial(boolean useAdvancedLinkCheck) throws Exception {
+		runProjectTestCase(useAdvancedLinkCheck);
 	}
 
-	@Test
-	public void test2_mutual() throws Exception {
-		runProjectTestCase();
+	@ParameterizedTest
+	@ValueSource(booleans = { false, true })
+	public void test2_mutual(boolean useAdvancedLinkCheck) throws Exception {
+		runProjectTestCase(useAdvancedLinkCheck);
 	}
 
-	@Test
-	public void test3_outside_tree() throws Exception {
-		runProjectTestCase();
+	@ParameterizedTest
+	@ValueSource(booleans = { false, true })
+	public void test3_outside_tree(boolean useAdvancedLinkCheck) throws Exception {
+		runProjectTestCase(useAdvancedLinkCheck);
 	}
 
-	@Test
-	public void test5_transitive_mutual() throws Exception {
-		runProjectTestCase();
+	@ParameterizedTest
+	@ValueSource(booleans = { false, true })
+	public void test5_transitive_mutual(boolean useAdvancedLinkCheck) throws Exception {
+		runProjectTestCase(useAdvancedLinkCheck);
 	}
 
-	@Test
-	public void test6_nonrecursive() throws Exception {
-		runProjectTestCase();
+	@ParameterizedTest
+	@ValueSource(booleans = { false, true })
+	public void test6_nonrecursive(boolean useAdvancedLinkCheck) throws Exception {
+		runProjectTestCase(useAdvancedLinkCheck);
 	}
 
-	private void runProjectTestCase() throws Exception {
-		// refresh should hang, if bug 105554 re-occurs
-		importProjectAndRefresh(testMethodName);
+	private void runProjectTestCase(boolean useAdvancedLinkCheck) throws Exception {
+		final boolean originalValue = UnifiedTree.isAdvancedRecursiveLinkChecksEnabled();
+		try {
+			UnifiedTree.enableAdvancedRecursiveLinkChecks(useAdvancedLinkCheck);
+			// refresh should hang, if bug 105554 re-occurs
+			importProjectAndRefresh(testMethodName);
+		} finally {
+			UnifiedTree.enableAdvancedRecursiveLinkChecks(originalValue);
+		}
 	}
 
 	private void importProjectAndRefresh(String projectName) throws Exception {
diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_recursiveLinks.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_recursiveLinks.java
index 34487877e938..3875bb952b1b 100644
--- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_recursiveLinks.java
+++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_recursiveLinks.java
@@ -13,8 +13,8 @@
 import static org.eclipse.core.tests.harness.FileSystemHelper.canCreateSymLinks;
 import static org.eclipse.core.tests.harness.FileSystemHelper.createSymLink;
 import static org.eclipse.core.tests.resources.ResourceTestUtil.createTestMonitor;
-import static org.junit.Assume.assumeTrue;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 import java.io.File;
 import java.io.IOException;
@@ -22,6 +22,7 @@
 import java.net.URI;
 import java.nio.file.Path;
 import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.internal.localstore.UnifiedTree;
 import org.eclipse.core.internal.resources.ProjectDescription;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
@@ -30,10 +31,11 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.tests.resources.util.WorkspaceResetExtension;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 /**
  * Tests for recursive symbolic links in projects.
@@ -47,7 +49,7 @@ public class Bug_185247_recursiveLinks {
 
 	@BeforeEach
 	public void requireCanCreateSymlinks(TestInfo testInfo) throws IOException {
-		assumeTrue("only relevant for platforms supporting symbolic links", canCreateSymLinks());
+		assumeTrue(canCreateSymLinks(), "only relevant for platforms supporting symbolic links");
 		testMethodName = testInfo.getTestMethod().get().getName();
 	}
 
@@ -62,13 +64,14 @@ public void requireCanCreateSymlinks(TestInfo testInfo) throws IOException {
 	 *         |-- link_current -> ./ (links "directory")
 	 * 
*/ - @Test - public void test1_linkCurrentDirectory() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test1_linkCurrentDirectory(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { createSymlink(directory, "link_current", "./"); }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } /** @@ -82,13 +85,14 @@ public void test1_linkCurrentDirectory() throws Exception { * |-- link_parent -> ../ (links "project root") * */ - @Test - public void test2_linkParentDirectory() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test2_linkParentDirectory(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { createSymlink(directory, "link_parent", "../"); }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } /** @@ -104,15 +108,16 @@ public void test2_linkParentDirectory() throws Exception { * |-- link_grandparent -> ../../ (links "project root") * */ - @Test - public void test3_linkGrandparentDirectory() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test3_linkGrandparentDirectory(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { File subdirectory = new File(directory, "subdirectory"); createDirectory(subdirectory); createSymlink(subdirectory, "link_grandparent", "../../"); }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } /** @@ -132,8 +137,9 @@ public void test3_linkGrandparentDirectory() throws Exception { * |-- link_parent -> ../ (links directory) * */ - @Test - public void test4_linkParentDirectoryTwice() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test4_linkParentDirectoryTwice(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { String[] subdirectoryNames = { "subdirectory1", "subdirectory2" }; for (String subdirectoryName : subdirectoryNames) { @@ -143,7 +149,7 @@ public void test4_linkParentDirectoryTwice() throws Exception { } }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } /** @@ -163,8 +169,9 @@ public void test4_linkParentDirectoryTwice() throws Exception { * |-- link_parent -> /tmp/<random string>/bug185247recursive/test5_linkParentDirectoyTwiceWithAbsolutePath/directory * */ - @Test - public void test5_linkParentDirectoyTwiceWithAbsolutePath() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test5_linkParentDirectoyTwiceWithAbsolutePath(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { String[] subdirectoryNames = { "subdirectory1", "subdirectory2" }; for (String subdirectoryName : subdirectoryNames) { @@ -174,22 +181,28 @@ public void test5_linkParentDirectoyTwiceWithAbsolutePath() throws Exception { } }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } - private void runTest(CreateTestProjectStructure createSymlinks) throws MalformedURLException, Exception { - String projectName = testMethodName; - IPath testRoot = IPath.fromPath(tempDirectory); - IPath projectRoot = testRoot.append("bug185247recursive").append(projectName); - File directory = projectRoot.append("directory").toFile(); - createDirectory(directory); - - createSymlinks.accept(directory); - - - URI projectRootLocation = URIUtil.toURI((projectRoot)); - // refreshing the project with recursive symlinks should not hang - importProjectAndRefresh(projectName, projectRootLocation); + private void runTest(CreateTestProjectStructure createSymlinks, boolean useAdvancedLinkCheck) + throws MalformedURLException, Exception { + final boolean originalValue = UnifiedTree.isAdvancedRecursiveLinkChecksEnabled(); + try { + UnifiedTree.enableAdvancedRecursiveLinkChecks(useAdvancedLinkCheck); + String projectName = testMethodName; + IPath testRoot = IPath.fromPath(tempDirectory); + IPath projectRoot = testRoot.append("bug185247recursive").append(projectName); + File directory = projectRoot.append("directory").toFile(); + createDirectory(directory); + + createSymlinks.accept(directory); + + URI projectRootLocation = URIUtil.toURI((projectRoot)); + // refreshing the project with recursive symlinks should not hang + importProjectAndRefresh(projectName, projectRootLocation); + } finally { + UnifiedTree.enableAdvancedRecursiveLinkChecks(originalValue); + } } private static void createDirectory(File directory) { diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/util/WorkspaceResetExtension.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/util/WorkspaceResetExtension.java index 937eeb73c1bf..81af73f6faff 100644 --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/util/WorkspaceResetExtension.java +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/util/WorkspaceResetExtension.java @@ -40,7 +40,7 @@ public class WorkspaceResetExtension implements AfterEachCallback, BeforeEachCal public void beforeEach(ExtensionContext context) throws Exception { // Wait for any pending refresh operation, in particular from startup waitForRefresh(); - TestUtil.log(IStatus.INFO, context.getDisplayName(), "setUp"); + TestUtil.log(IStatus.INFO, getTestName(context), "setUp"); assertNotNull(getWorkspace(), "Workspace was not set up"); FreezeMonitor.expectCompletionInAMinute(); waitForRefresh(); @@ -48,7 +48,7 @@ public void beforeEach(ExtensionContext context) throws Exception { @Override public void afterEach(ExtensionContext context) throws Exception { - TestUtil.log(IStatus.INFO, context.getDisplayName(), "tearDown"); + TestUtil.log(IStatus.INFO, getTestName(context), "tearDown"); try { restoreCleanWorkspace(); } finally { @@ -57,6 +57,16 @@ public void afterEach(ExtensionContext context) throws Exception { } } + private String getTestName(ExtensionContext context) { + String className = context.getRequiredTestClass().getSimpleName(); + String methodName = context.getRequiredTestMethod().getName(); + String displayName = context.getDisplayName(); + if (!displayName.contains(methodName)) { + methodName += displayName; + } + return className + "." + methodName; + } + private void restoreCleanWorkspace() { List exceptions = new ArrayList<>(); try { From f752dd4862a6ace37310992daaa16ec6d271e064 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Wed, 5 Nov 2025 03:23:48 +0000 Subject: [PATCH 36/56] Perform clean code of runtime/bundles/org.eclipse.core.contenttype --- .../core/runtime/content/XMLRootElementContentDescriber.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/XMLRootElementContentDescriber.java b/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/XMLRootElementContentDescriber.java index 7fe6dc86300e..d86a3319fded 100644 --- a/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/XMLRootElementContentDescriber.java +++ b/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/XMLRootElementContentDescriber.java @@ -96,6 +96,7 @@ private int checkCriteria(Map properties) throws IOException { /* (Intentionally not included in javadoc) * @see IContentDescriber#describe(InputStream, IContentDescription) */ + @Deprecated @Override public int describe(InputStream contents, IContentDescription description) throws IOException { return describe(contents, description, new HashMap<>()); @@ -104,6 +105,7 @@ public int describe(InputStream contents, IContentDescription description) throw /** * @noreference This method is not intended to be referenced by clients. */ + @Deprecated public int describe(InputStream contents, IContentDescription description, Map properties) throws IOException { // call the basic XML describer to do basic recognition if (super.describe2(contents, description, properties) == INVALID) { @@ -118,6 +120,7 @@ public int describe(InputStream contents, IContentDescription description, Map()); @@ -126,6 +129,7 @@ public int describe(Reader contents, IContentDescription description) throws IOE /** * @noreference This method is not intended to be referenced by clients. */ + @Deprecated public int describe(Reader contents, IContentDescription description, Map properties) throws IOException { // call the basic XML describer to do basic recognition if (super.describe2(contents, description, properties) == INVALID) { @@ -140,6 +144,7 @@ public int describe(Reader contents, IContentDescription description, Map Date: Wed, 5 Nov 2025 03:00:38 +0000 Subject: [PATCH 37/56] Perform clean code of debug/org.eclipse.debug.ui --- .../internal/ui/viewers/PartPresentationContext.java | 2 ++ .../eclipse/debug/ui/DebugElementWorkbenchAdapter.java | 5 +++++ .../debug/ui/DeferredDebugElementWorkbenchAdapter.java | 4 ++++ .../ui/org/eclipse/debug/ui/actions/LaunchAsAction.java | 8 ++++++++ .../ui/actions/RulerBreakpointTypesActionDelegate.java | 7 +++++++ 5 files changed, 26 insertions(+) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java index 1e2f148f23a3..89b81e73ca72 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java @@ -30,10 +30,12 @@ public class PartPresentationContext extends PresentationContext { * * @param part part */ + @Deprecated public PartPresentationContext(IWorkbenchPart part) { super(part); } + @Deprecated @Override public IWorkbenchPart getPart() { return super.getPart(); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugElementWorkbenchAdapter.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugElementWorkbenchAdapter.java index 310bdbcea266..5da15f783104 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugElementWorkbenchAdapter.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugElementWorkbenchAdapter.java @@ -37,26 +37,31 @@ @Deprecated public abstract class DebugElementWorkbenchAdapter implements IWorkbenchAdapter, IWorkbenchAdapter2 { + @Deprecated @Override public ImageDescriptor getImageDescriptor(Object object) { return DebugElementHelper.getImageDescriptor(object); } + @Deprecated @Override public String getLabel(Object o) { return DebugElementHelper.getLabel(o); } + @Deprecated @Override public RGB getForeground(Object element) { return DebugElementHelper.getForeground(element); } + @Deprecated @Override public RGB getBackground(Object element) { return DebugElementHelper.getBackground(element); } + @Deprecated @Override public FontData getFont(Object element) { return DebugElementHelper.getFont(element); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DeferredDebugElementWorkbenchAdapter.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DeferredDebugElementWorkbenchAdapter.java index 755daac87f1a..7bb540e485d7 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DeferredDebugElementWorkbenchAdapter.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DeferredDebugElementWorkbenchAdapter.java @@ -39,18 +39,22 @@ public abstract class DeferredDebugElementWorkbenchAdapter extends DebugElementW /** * An empty collection of children */ + @Deprecated protected static final Object[] EMPTY = new Object[0]; + @Deprecated @Override public boolean isContainer() { return true; } + @Deprecated @Override public ISchedulingRule getRule(Object object) { return null; } + @Deprecated @Override public void fetchDeferredChildren(Object object, IElementCollector collector, IProgressMonitor monitor) { if (monitor.isCanceled()) { diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAsAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAsAction.java index 26645199cae7..997358e721a7 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAsAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAsAction.java @@ -76,6 +76,7 @@ public class LaunchAsAction extends Action implements IMenuCreator, IWorkbenchWi * * @param launchGroupIdentifier launch group identifier */ + @Deprecated public LaunchAsAction(String launchGroupIdentifier) { super(); fLaunchGroupIdentifier = launchGroupIdentifier; @@ -96,6 +97,7 @@ private LaunchGroupExtension getLaunchGroup() { /** * @see IAction#run() */ + @Deprecated @Override public void run() { //do nothing, this action just creates a cascading menu. @@ -118,6 +120,7 @@ private void createAction(Menu parent, IAction action, int count) { /** * @see IMenuCreator#dispose() */ + @Deprecated @Override public void dispose() { if (getCreatedMenu() != null) { @@ -128,6 +131,7 @@ public void dispose() { /** * @see IMenuCreator#getMenu(Control) */ + @Deprecated @Override public Menu getMenu(Control parent) { return null; @@ -136,6 +140,7 @@ public Menu getMenu(Control parent) { /** * @see IMenuCreator#getMenu(Menu) */ + @Deprecated @Override public Menu getMenu(Menu parent) { if (getCreatedMenu() != null) { @@ -267,6 +272,7 @@ private LaunchConfigurationManager getLaunchConfigurationManager() { /** * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) */ + @Deprecated @Override public void init(IWorkbenchWindow window) { // if (window instanceof WorkbenchWindow) { @@ -277,6 +283,7 @@ public void init(IWorkbenchWindow window) { /** * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) */ + @Deprecated @Override public void run(IAction action) { // do nothing - this is just a menu @@ -285,6 +292,7 @@ public void run(IAction action) { /** * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) */ + @Deprecated @Override public void selectionChanged(IAction action, ISelection selection) { if (fAction == null) { diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RulerBreakpointTypesActionDelegate.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RulerBreakpointTypesActionDelegate.java index 60c14b0a9ad6..99acc808df42 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RulerBreakpointTypesActionDelegate.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RulerBreakpointTypesActionDelegate.java @@ -111,16 +111,19 @@ public void run() { } + @Deprecated @Override public void selectionChanged(IAction action, ISelection selection) { // In the editor we're not using the selection. } + @Deprecated @Override public void run(IAction action) { // Do nothing, this is a pull-down menu. } + @Deprecated @Override public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) { // Clean up old editor data. @@ -148,6 +151,7 @@ public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) { } + @Deprecated @Override public void dispose() { if (fCallerAction != null) { @@ -159,6 +163,7 @@ public void dispose() { fRulerInfo = null; } + @Deprecated @Override public void menuAboutToShow(IMenuManager manager) { fSelection = StructuredSelection.EMPTY; @@ -196,6 +201,7 @@ private void setMenu(Menu menu) { fMenu = menu; } + @Deprecated @Override public Menu getMenu(Menu parent) { setMenu(new Menu(parent)); @@ -204,6 +210,7 @@ public Menu getMenu(Menu parent) { return fMenu; } + @Deprecated @Override public Menu getMenu(Control parent) { setMenu(new Menu(parent)); From 5ed7afaa1c6fcb9446defb5b3861a704ca9679b6 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 6 Nov 2025 04:33:27 +0000 Subject: [PATCH 38/56] Perform clean code of update/org.eclipse.update.configurator --- .../configurator/IPlatformConfiguration.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java index b298f53891c6..0176d8c63686 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java +++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java @@ -53,6 +53,7 @@ public interface ISiteEntry { * @return site url * @since 2.0 */ + @Deprecated public URL getURL(); /** @@ -61,6 +62,7 @@ public interface ISiteEntry { * @return site policy * @since 2.0 */ + @Deprecated public ISitePolicy getSitePolicy(); /** @@ -69,6 +71,7 @@ public interface ISiteEntry { * @param policy site policy * @since 2.0 */ + @Deprecated public void setSitePolicy(ISitePolicy policy); /** @@ -79,6 +82,7 @@ public interface ISiteEntry { * A feature entry is returned as a path relative to the site URL * @since 2.0 */ + @Deprecated public String[] getFeatures(); /** @@ -91,6 +95,7 @@ public interface ISiteEntry { * A plug-in entry is returned as a path relative to the site URL * * @since 2.0 */ + @Deprecated public String[] getPlugins(); /** @@ -101,6 +106,7 @@ public interface ISiteEntry { * @return site change stamp * @since 2.0 */ + @Deprecated public long getChangeStamp(); /** @@ -133,6 +139,7 @@ public interface ISiteEntry { * @return true if site can be updated, false otherwise * @since 2.0 */ + @Deprecated public boolean isUpdateable(); /** @@ -143,6 +150,7 @@ public interface ISiteEntry { * @return true if the site is linked, false otherwise * @since 2.0 */ + @Deprecated public boolean isNativelyLinked(); } @@ -180,6 +188,7 @@ public interface ISitePolicy { * policy type is interpreted as path entries to included plugin.xml * or fragment.xml relative to the site URL */ + @Deprecated public static final int USER_INCLUDE = 0; /** @@ -187,6 +196,7 @@ public interface ISitePolicy { * policy type is interpreted as path entries to excluded plugin.xml * or fragment.xml relative to the site URL */ + @Deprecated public static final int USER_EXCLUDE = 1; /** @@ -194,6 +204,7 @@ public interface ISitePolicy { * are contributed to the runtime. * @since 3.1 */ + @Deprecated public static final int MANAGED_ONLY = 2; /** @@ -202,6 +213,7 @@ public interface ISitePolicy { * @return policy type * @since 2.0 */ + @Deprecated public int getType(); /** @@ -210,6 +222,7 @@ public interface ISitePolicy { * @return the list as an array * @since 2.0 */ + @Deprecated public String[] getList(); /** @@ -222,6 +235,7 @@ public interface ISitePolicy { * @see #USER_EXCLUDE * @since 2.0 */ + @Deprecated public void setList(String[] list); } @@ -245,6 +259,7 @@ public interface IFeatureEntry { * @return feature identifier * @since 2.0 */ + @Deprecated public String getFeatureIdentifier(); /** @@ -252,6 +267,7 @@ public interface IFeatureEntry { * @return feature version (as string), or null * @since 2.0 */ + @Deprecated public String getFeatureVersion(); /** @@ -266,6 +282,7 @@ public interface IFeatureEntry { * @return feature identifier (as string), or null * @since 2.1 */ + @Deprecated public String getFeaturePluginIdentifier(); /** @@ -280,6 +297,7 @@ public interface IFeatureEntry { * @return feature version (as string), or null * @since 2.0 */ + @Deprecated public String getFeaturePluginVersion(); /** @@ -288,6 +306,7 @@ public interface IFeatureEntry { * @return application identifier, or null * @since 2.0 */ + @Deprecated public String getFeatureApplication(); /** @@ -298,6 +317,7 @@ public interface IFeatureEntry { * @return array of URLs, or an empty array * @since 2.0 */ + @Deprecated public URL[] getFeatureRootURLs(); /** @@ -307,6 +327,7 @@ public interface IFeatureEntry { * false otherwise. * @since 2.0 */ + @Deprecated public boolean canBePrimary(); } From 7c9185faa9f1229cae5fedbf2154fb117196da90 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 6 Nov 2025 03:17:12 +0000 Subject: [PATCH 39/56] Perform clean code of resources/bundles/org.eclipse.core.resources --- .../org/eclipse/core/resources/IFileModificationValidator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFileModificationValidator.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFileModificationValidator.java index efc60fd5760d..c70f8d052f74 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFileModificationValidator.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFileModificationValidator.java @@ -49,6 +49,7 @@ public interface IFileModificationValidator { * reasons why modifying the given files is not reasonable * @see IWorkspace#validateEdit(IFile[], Object) */ + @Deprecated IStatus validateEdit(IFile[] files, Object context); /** @@ -67,5 +68,6 @@ public interface IFileModificationValidator { * @see IFile#setContents(java.io.InputStream, int, org.eclipse.core.runtime.IProgressMonitor) * @see IFile#appendContents(java.io.InputStream, int, org.eclipse.core.runtime.IProgressMonitor) */ + @Deprecated IStatus validateSave(IFile file); } From 9f188d2c603df59c5c05c7284c001869777aa535 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Wed, 5 Nov 2025 02:45:09 +0000 Subject: [PATCH 40/56] Perform clean code of debug/org.eclipse.debug.core --- .../core/org/eclipse/debug/core/model/IFilteredStep.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/IFilteredStep.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/IFilteredStep.java index 566d367fa521..13dcc0d45ba8 100644 --- a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/IFilteredStep.java +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/IFilteredStep.java @@ -33,6 +33,7 @@ public interface IFilteredStep extends IStep { * * @return whether this element can currently perform a filtered step into */ + @Deprecated boolean canStepWithFilters(); /** * Steps into the current statement, generating RESUME @@ -46,5 +47,6 @@ public interface IFilteredStep extends IStep { *
  • NOT_SUPPORTED - The capability is not supported by the target
  • * */ + @Deprecated void stepWithFilters() throws DebugException; } From 5564079942577d67ffeef44657f7b97c0b55a094 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 6 Nov 2025 03:24:42 +0000 Subject: [PATCH 41/56] Perform clean code of runtime/bundles/org.eclipse.core.runtime --- .../legacy/PreferenceForwarder.java | 41 +++++++++++++++ .../org/eclipse/core/runtime/Preferences.java | 52 +++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/preferences/legacy/PreferenceForwarder.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/preferences/legacy/PreferenceForwarder.java index 83d74ba34b4d..84bd19e5d1e3 100644 --- a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/preferences/legacy/PreferenceForwarder.java +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/preferences/legacy/PreferenceForwarder.java @@ -47,10 +47,12 @@ public class PreferenceForwarder extends Preferences implements IEclipsePreferen /* * Used for test suites only. */ + @Deprecated public PreferenceForwarder(String pluginID) { this(null, pluginID); } + @Deprecated public PreferenceForwarder(Object plugin, String pluginID) { super(); this.plugin = plugin; @@ -60,6 +62,7 @@ public PreferenceForwarder(Object plugin, String pluginID) { /* * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#added(org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent) */ + @Deprecated @Override public synchronized void added(IEclipsePreferences.NodeChangeEvent event) { if (listeners.size() > 0 && pluginID.equals(event.getChild().name())) { @@ -75,6 +78,7 @@ public synchronized void added(IEclipsePreferences.NodeChangeEvent event) { /* * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#removed(org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent) */ + @Deprecated @Override public synchronized void removed(IEclipsePreferences.NodeChangeEvent event) { // Do nothing. We can't remove ourselves from the node's list of preference change @@ -87,6 +91,7 @@ public synchronized void removed(IEclipsePreferences.NodeChangeEvent event) { * * @param listener a property change listener */ + @Deprecated @Override public synchronized void addPropertyChangeListener(IPropertyChangeListener listener) { if (listeners.size() == 0) { @@ -103,6 +108,7 @@ public synchronized void addPropertyChangeListener(IPropertyChangeListener liste /* * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent) */ + @Deprecated @Override public void preferenceChange(IEclipsePreferences.PreferenceChangeEvent event) { // if we are the ones making this change, then don't broadcast @@ -145,6 +151,7 @@ private IEclipsePreferences getDefaultPreferences() { * * @param listener a property change listener */ + @Deprecated @Override public synchronized void removePropertyChangeListener(IPropertyChangeListener listener) { listeners.remove(listener); @@ -194,6 +201,7 @@ private Object getDefault(String key, Object obj) { * @return true if either a current value or a default * value is known for the named property, and falseotherwise */ + @Deprecated @Override public boolean contains(String name) { if (name == null) { @@ -216,6 +224,7 @@ public boolean contains(String name) { * @param name the name of the property * @return the boolean-valued property */ + @Deprecated @Override public boolean getBoolean(String name) { return getPluginPreferences(true).getBoolean(name, getDefaultPreferences().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT)); @@ -240,6 +249,7 @@ public boolean getBoolean(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated @Override public void setValue(String name, boolean value) { Boolean oldValue = getBoolean(name) ? Boolean.TRUE : Boolean.FALSE; @@ -270,6 +280,7 @@ public void setValue(String name, boolean value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public boolean getDefaultBoolean(String name) { return getDefaultPreferences().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT); @@ -290,6 +301,7 @@ public boolean getDefaultBoolean(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated @Override public void setDefault(String name, boolean value) { getDefaultPreferences().putBoolean(name, value); @@ -305,6 +317,7 @@ public void setDefault(String name, boolean value) { * @param name the name of the property * @return the double-valued property */ + @Deprecated @Override public double getDouble(String name) { return getPluginPreferences(true).getDouble(name, getDefaultPreferences().getDouble(name, DOUBLE_DEFAULT_DEFAULT)); @@ -330,6 +343,7 @@ public double getDouble(String name) { * @param value the new current value of the property; must be * a number (not a NaN) */ + @Deprecated @Override public void setValue(String name, double value) { if (Double.isNaN(value)) { @@ -364,6 +378,7 @@ public void setValue(String name, double value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public double getDefaultDouble(String name) { return getDefaultPreferences().getDouble(name, DOUBLE_DEFAULT_DEFAULT); @@ -385,6 +400,7 @@ public double getDefaultDouble(String name) { * @param value the new default value for the property; must be * a number (not a NaN) */ + @Deprecated @Override public void setDefault(String name, double value) { if (Double.isNaN(value)) { @@ -403,6 +419,7 @@ public void setDefault(String name, double value) { * @param name the name of the property * @return the float-valued property */ + @Deprecated @Override public float getFloat(String name) { return getPluginPreferences(true).getFloat(name, getDefaultPreferences().getFloat(name, FLOAT_DEFAULT_DEFAULT)); @@ -428,6 +445,7 @@ public float getFloat(String name) { * @param value the new current value of the property; must be * a number (not a NaN) */ + @Deprecated @Override public void setValue(String name, float value) { if (Float.isNaN(value)) { @@ -462,6 +480,7 @@ public void setValue(String name, float value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public float getDefaultFloat(String name) { return getDefaultPreferences().getFloat(name, FLOAT_DEFAULT_DEFAULT); @@ -483,6 +502,7 @@ public float getDefaultFloat(String name) { * @param value the new default value for the property; must be * a number (not a NaN) */ + @Deprecated @Override public void setDefault(String name, float value) { if (Float.isNaN(value)) { @@ -501,6 +521,7 @@ public void setDefault(String name, float value) { * @param name the name of the property * @return the int-valued property */ + @Deprecated @Override public int getInt(String name) { return getPluginPreferences(true).getInt(name, getDefaultPreferences().getInt(name, INT_DEFAULT_DEFAULT)); @@ -525,6 +546,7 @@ public int getInt(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated @Override public void setValue(String name, int value) { final int intValue = getInt(name); @@ -556,6 +578,7 @@ public void setValue(String name, int value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public int getDefaultInt(String name) { return getDefaultPreferences().getInt(name, INT_DEFAULT_DEFAULT); @@ -576,6 +599,7 @@ public int getDefaultInt(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated @Override public void setDefault(String name, int value) { getDefaultPreferences().putInt(name, value); @@ -591,6 +615,7 @@ public void setDefault(String name, int value) { * @param name the name of the property * @return the long-valued property */ + @Deprecated @Override public long getLong(String name) { return getPluginPreferences(true).getLong(name, getDefaultPreferences().getLong(name, LONG_DEFAULT_DEFAULT)); @@ -615,6 +640,7 @@ public long getLong(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated @Override public void setValue(String name, long value) { final long longValue = getLong(name); @@ -646,6 +672,7 @@ public void setValue(String name, long value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public long getDefaultLong(String name) { return getDefaultPreferences().getLong(name, LONG_DEFAULT_DEFAULT); @@ -666,6 +693,7 @@ public long getDefaultLong(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated @Override public void setDefault(String name, long value) { getDefaultPreferences().putLong(name, value); @@ -680,6 +708,7 @@ public void setDefault(String name, long value) { * @param name the name of the property * @return the string-valued property */ + @Deprecated @Override public String getString(String name) { return getPluginPreferences(true).get(name, getDefaultPreferences().get(name, STRING_DEFAULT_DEFAULT)); @@ -704,6 +733,7 @@ public String getString(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated @Override public void setValue(String name, String value) { if (value == null) { @@ -736,6 +766,7 @@ public void setValue(String name, String value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public String getDefaultString(String name) { return getDefaultPreferences().get(name, STRING_DEFAULT_DEFAULT); @@ -756,6 +787,7 @@ public String getDefaultString(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated @Override public void setDefault(String name, String value) { if (value == null) { @@ -773,6 +805,7 @@ public void setDefault(String name, String value) { * and false otherwise (including the case where the property * is unknown to this object) */ + @Deprecated @Override public boolean isDefault(String name) { if (name == null) { @@ -800,6 +833,7 @@ public boolean isDefault(String name) { * * @param name the name of the property */ + @Deprecated @Override public void setToDefault(String name) { IEclipsePreferences preferences = getPluginPreferences(true); @@ -815,6 +849,7 @@ public void setToDefault(String name) { * * @return an array of property names */ + @Deprecated @Override public String[] propertyNames() { return getPluginPreferences(true).keys(); @@ -826,6 +861,7 @@ public String[] propertyNames() { * * @return an array of property names */ + @Deprecated @Override public String[] defaultPropertyNames() { try { @@ -844,6 +880,7 @@ public String[] defaultPropertyNames() { * known to this preference object has a current value different from its * default value, and false otherwise */ + @Deprecated @Override public boolean needsSaving() { return getPluginPreferences(true).isDirty(); @@ -852,6 +889,7 @@ public boolean needsSaving() { /** * Flush the values of these plug-in preferences to disk. */ + @Deprecated public void flush() throws BackingStoreException { IEclipsePreferences node = getPluginPreferences(false); if (node != null) { @@ -870,6 +908,7 @@ private void logError(String message, Exception e) { /* * @see org.eclipse.core.runtime.Preferences#load(java.io.InputStream) */ + @Deprecated @Override public void load(InputStream in) throws IOException { Properties result = new Properties(); @@ -888,6 +927,7 @@ public void load(InputStream in) throws IOException { /* * @see org.eclipse.core.runtime.Preferences#store(java.io.OutputStream, java.lang.String) */ + @Deprecated @Override public void store(OutputStream out, String header) throws IOException { Properties result = convertToProperties(); @@ -913,6 +953,7 @@ private void convertFromProperties(Properties props) { } } + @Deprecated @Override public String toString() { return "PreferenceForwarder(" + pluginID + ")"; //$NON-NLS-1$ //$NON-NLS-2$ diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java index dfdc23c44b8b..96c2146c0570 100644 --- a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java @@ -98,43 +98,51 @@ public class Preferences { /** * The default-default value for boolean properties (false). */ + @Deprecated public static final boolean BOOLEAN_DEFAULT_DEFAULT = false; /** * The default-default value for double properties (0.0). */ + @Deprecated public static final double DOUBLE_DEFAULT_DEFAULT = 0.0; /** * The default-default value for float properties (0.0f). */ + @Deprecated public static final float FLOAT_DEFAULT_DEFAULT = 0.0f; /** * The default-default value for int properties (0). */ + @Deprecated public static final int INT_DEFAULT_DEFAULT = 0; /** * The default-default value for long properties (0L). */ + @Deprecated public static final long LONG_DEFAULT_DEFAULT = 0L; /** * The default-default value for String properties (""). */ + @Deprecated public static final String STRING_DEFAULT_DEFAULT = ""; //$NON-NLS-1$ /** * The string representation used for true * ("true"). */ + @Deprecated protected static final String TRUE = "true"; //$NON-NLS-1$ /** * The string representation used for false * ("false"). */ + @Deprecated protected static final String FALSE = "false"; //$NON-NLS-1$ /** @@ -150,6 +158,7 @@ public class Preferences { * * @since 3.2 */ + @Deprecated public static final String PT_PREFERENCES = "preferences"; //$NON-NLS-1$ /** @@ -168,6 +177,7 @@ public class Preferences { * @see Preferences#addPropertyChangeListener(Preferences.IPropertyChangeListener) * @see Preferences.IPropertyChangeListener */ + @Deprecated public static class PropertyChangeEvent extends EventObject { /** * All serializable objects should have a stable serialVersionUID @@ -272,6 +282,7 @@ public Object getOldValue() { * three cases in their implementation of the property change listener. *

    */ + @Deprecated @FunctionalInterface public interface IPropertyChangeListener extends EventListener { @@ -294,6 +305,7 @@ public interface IPropertyChangeListener extends EventListener { * These listeners are to be informed when the current value of a property * changes. */ + @Deprecated protected ListenerList listeners = new ListenerList<>(); /** @@ -313,6 +325,7 @@ public interface IPropertyChangeListener extends EventListener { * Indicates whether a value has been changed by setToDefault * or setValue; initially false. */ + @Deprecated protected boolean dirty = false; /** @@ -330,6 +343,7 @@ public interface IPropertyChangeListener extends EventListener { * @see #importPreferences(IPath) * @see #validatePreferenceVersions(IPath) */ + @Deprecated public static void exportPreferences(IPath path) throws CoreException { File file = path.toFile(); if (file.exists()) { @@ -372,6 +386,7 @@ public static void exportPreferences(IPath path) throws CoreException { * @see #exportPreferences(IPath) * @see #validatePreferenceVersions(IPath) */ + @Deprecated public static void importPreferences(IPath path) throws CoreException { if (!path.toFile().exists()) { String msg = NLS.bind(PrefsMessages.preferences_fileNotFound, path.toOSString()); @@ -410,6 +425,7 @@ public static void importPreferences(IPath path) throws CoreException { * @see #exportPreferences(IPath) * @see #importPreferences(IPath) */ + @Deprecated public static IStatus validatePreferenceVersions(IPath file) { PreferencesService service = PreferencesService.getDefault(); return service.validateVersions(file); @@ -424,6 +440,7 @@ public static IStatus validatePreferenceVersions(IPath file) { * @see #load(InputStream) * @see #store(OutputStream, String) */ + @Deprecated public Preferences() { defaultProperties = new Properties(); properties = new Properties(defaultProperties); @@ -441,6 +458,7 @@ public Preferences() { *

    * @param listener a property change listener */ + @Deprecated public void addPropertyChangeListener(IPropertyChangeListener listener) { listeners.add(listener); } @@ -451,6 +469,7 @@ public void addPropertyChangeListener(IPropertyChangeListener listener) { * * @param listener a property change listener */ + @Deprecated public void removePropertyChangeListener(IPropertyChangeListener listener) { listeners.remove(listener); } @@ -464,6 +483,7 @@ public void removePropertyChangeListener(IPropertyChangeListener listener) { * @return true if either a current value or a default * value is known for the named property, and falseotherwise */ + @Deprecated public boolean contains(String name) { return (properties.containsKey(name) || defaultProperties.containsKey(name)); } @@ -479,6 +499,7 @@ public boolean contains(String name) { * @param newValue the new value, or null if not known or not * relevant */ + @Deprecated protected void firePropertyChangeEvent(String name, Object oldValue, Object newValue) { if (name == null) { throw new IllegalArgumentException(); @@ -515,6 +536,7 @@ public void run() throws Exception { * @param name the name of the property * @return the boolean-valued property */ + @Deprecated public boolean getBoolean(String name) { String value = properties.getProperty(name); if (value == null) { @@ -542,6 +564,7 @@ public boolean getBoolean(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated public void setValue(String name, boolean value) { boolean defaultValue = getDefaultBoolean(name); boolean oldValue = getBoolean(name); @@ -573,6 +596,7 @@ public void setValue(String name, boolean value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public boolean getDefaultBoolean(String name) { String value = defaultProperties.getProperty(name); if (value == null) { @@ -596,6 +620,7 @@ public boolean getDefaultBoolean(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated public void setDefault(String name, boolean value) { defaultProperties.put(name, value ? Preferences.TRUE : Preferences.FALSE); } @@ -611,6 +636,7 @@ public void setDefault(String name, boolean value) { * @param name the name of the property * @return the double-valued property */ + @Deprecated public double getDouble(String name) { return convertToDouble(properties.getProperty(name), DOUBLE_DEFAULT_DEFAULT); } @@ -635,6 +661,7 @@ public double getDouble(String name) { * @param value the new current value of the property; must be * a number (not a NaN) */ + @Deprecated public void setValue(String name, double value) { if (Double.isNaN(value)) { throw new IllegalArgumentException(); @@ -669,6 +696,7 @@ public void setValue(String name, double value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public double getDefaultDouble(String name) { return convertToDouble(defaultProperties.getProperty(name), DOUBLE_DEFAULT_DEFAULT); } @@ -689,6 +717,7 @@ public double getDefaultDouble(String name) { * @param value the new default value for the property; must be * a number (not a NaN) */ + @Deprecated public void setDefault(String name, double value) { if (Double.isNaN(value)) { throw new IllegalArgumentException(); @@ -729,6 +758,7 @@ private double convertToDouble(String rawPropertyValue, double defaultValue) { * @param name the name of the property * @return the float-valued property */ + @Deprecated public float getFloat(String name) { return convertToFloat(properties.getProperty(name), FLOAT_DEFAULT_DEFAULT); } @@ -753,6 +783,7 @@ public float getFloat(String name) { * @param value the new current value of the property; must be * a number (not a NaN) */ + @Deprecated public void setValue(String name, float value) { if (Float.isNaN(value)) { throw new IllegalArgumentException(); @@ -787,6 +818,7 @@ public void setValue(String name, float value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public float getDefaultFloat(String name) { return convertToFloat(defaultProperties.getProperty(name), FLOAT_DEFAULT_DEFAULT); } @@ -807,6 +839,7 @@ public float getDefaultFloat(String name) { * @param value the new default value for the property; must be * a number (not a NaN) */ + @Deprecated public void setDefault(String name, float value) { if (Float.isNaN(value)) { throw new IllegalArgumentException(); @@ -847,6 +880,7 @@ private float convertToFloat(String rawPropertyValue, float defaultValue) { * @param name the name of the property * @return the int-valued property */ + @Deprecated public int getInt(String name) { return convertToInt(properties.getProperty(name), INT_DEFAULT_DEFAULT); } @@ -870,6 +904,7 @@ public int getInt(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated public void setValue(String name, int value) { int defaultValue = getDefaultInt(name); int oldValue = getInt(name); @@ -901,6 +936,7 @@ public void setValue(String name, int value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public int getDefaultInt(String name) { return convertToInt(defaultProperties.getProperty(name), INT_DEFAULT_DEFAULT); } @@ -920,6 +956,7 @@ public int getDefaultInt(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated public void setDefault(String name, int value) { defaultProperties.put(name, Integer.toString(value)); } @@ -957,6 +994,7 @@ private int convertToInt(String rawPropertyValue, int defaultValue) { * @param name the name of the property * @return the long-valued property */ + @Deprecated public long getLong(String name) { return convertToLong(properties.getProperty(name), LONG_DEFAULT_DEFAULT); } @@ -980,6 +1018,7 @@ public long getLong(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated public void setValue(String name, long value) { long defaultValue = getDefaultLong(name); long oldValue = getLong(name); @@ -1011,6 +1050,7 @@ public void setValue(String name, long value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public long getDefaultLong(String name) { return convertToLong(defaultProperties.getProperty(name), LONG_DEFAULT_DEFAULT); } @@ -1030,6 +1070,7 @@ public long getDefaultLong(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated public void setDefault(String name, long value) { defaultProperties.put(name, Long.toString(value)); } @@ -1066,6 +1107,7 @@ private long convertToLong(String rawPropertyValue, long defaultValue) { * @param name the name of the property * @return the string-valued property */ + @Deprecated public String getString(String name) { String value = properties.getProperty(name); return (value != null ? value : STRING_DEFAULT_DEFAULT); @@ -1090,6 +1132,7 @@ public String getString(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated public void setValue(String name, String value) { if (value == null) { throw new IllegalArgumentException(); @@ -1124,6 +1167,7 @@ public void setValue(String name, String value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public String getDefaultString(String name) { String value = defaultProperties.getProperty(name); return (value != null ? value : STRING_DEFAULT_DEFAULT); @@ -1144,6 +1188,7 @@ public String getDefaultString(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated public void setDefault(String name, String value) { if (value == null) { throw new IllegalArgumentException(); @@ -1161,6 +1206,7 @@ public void setDefault(String name, String value) { * and false otherwise (including the case where the property * is unknown to this object) */ + @Deprecated public boolean isDefault(String name) { return !properties.containsKey(name); } @@ -1184,6 +1230,7 @@ public boolean isDefault(String name) { * * @param name the name of the property */ + @Deprecated public void setToDefault(String name) { Object oldPropertyValue = properties.remove(name); if (oldPropertyValue != null) { @@ -1201,6 +1248,7 @@ public void setToDefault(String name) { * * @return an array of property names */ + @Deprecated public String[] propertyNames() { return properties.keySet().toArray(EMPTY_STRING_ARRAY); } @@ -1211,6 +1259,7 @@ public String[] propertyNames() { * * @return an array of property names */ + @Deprecated public String[] defaultPropertyNames() { return defaultProperties.keySet().toArray(EMPTY_STRING_ARRAY); } @@ -1223,6 +1272,7 @@ public String[] defaultPropertyNames() { * known to this preference object has a current value different from its * default value, and false otherwise */ + @Deprecated public boolean needsSaving() { return dirty; } @@ -1242,6 +1292,7 @@ public boolean needsSaving() { * @exception IOException if there is a problem saving this preference object * @see Properties#store(OutputStream,String) */ + @Deprecated public void store(OutputStream out, String header) throws IOException { properties.store(out, header); dirty = false; @@ -1258,6 +1309,7 @@ public void store(OutputStream out, String header) throws IOException { * object * @see java.util.Properties#load(InputStream) */ + @Deprecated public void load(InputStream in) throws IOException { properties.load(in); dirty = false; From eda2f3ee2bcbe2477ef4288c7c6ef7930c472975 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Thu, 6 Nov 2025 09:58:24 +0000 Subject: [PATCH 42/56] Perform clean code of runtime/bundles/org.eclipse.core.runtime --- .../src/org/eclipse/core/runtime/Preferences.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java index 96c2146c0570..bc9bff881856 100644 --- a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java @@ -212,6 +212,7 @@ public static class PropertyChangeEvent extends EventObject { * @param newValue the new value of the property, or * null if none */ + @Deprecated protected PropertyChangeEvent(Object source, String property, Object oldValue, Object newValue) { super(source); @@ -233,6 +234,7 @@ protected PropertyChangeEvent(Object source, String property, Object oldValue, O * * @return the name of the property that changed */ + @Deprecated public String getProperty() { return propertyName; } @@ -243,6 +245,7 @@ public String getProperty() { * @return the new value, or null if not known * or not relevant */ + @Deprecated public Object getNewValue() { return newValue; } @@ -253,6 +256,7 @@ public Object getNewValue() { * @return the old value, or null if not known * or not relevant */ + @Deprecated public Object getOldValue() { return oldValue; } @@ -296,6 +300,7 @@ public interface IPropertyChangeListener extends EventListener { * @param event the property change event object describing which * property changed and how */ + @Deprecated public void propertyChange(Preferences.PropertyChangeEvent event); } From 440accda0972c30b58b72e79ee8ff5382d5c3812 Mon Sep 17 00:00:00 2001 From: Andrey Loskutov Date: Wed, 5 Nov 2025 17:40:52 +0100 Subject: [PATCH 43/56] LocationMap should use HashMap with TreeSet for better performance The TreeMap data retrieval is slower compared to HashMap and TreeMap "sorted" behavior is only used in matchingPrefixDo() and overLappingResourcesDo() while updating resources. Reading unchanged data will be faster if using HashMap, updating the data will use TreeSet and still be as fast as before. Fixes https://github.com/eclipse-platform/eclipse.platform/issues/2251 --- .../core/internal/resources/AliasManager.java | 64 +++++++++++++++---- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java index 0112726a74ee..2fdcf71f8a75 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java @@ -24,10 +24,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map.Entry; import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; import org.eclipse.core.filesystem.EFS; @@ -126,15 +125,56 @@ public void accept(IResource match) { } + /** + * A HashMap that also maintains its keys in sorted order. It combines the fast + * access to the content with the ability to get sorted keys and key subsets. + */ + private static final class HashMapWithSortedKeys { + private final SortedSet keys; + private final HashMap map; + + HashMapWithSortedKeys() { + keys = new TreeSet<>(IFileStore::compareTo); + map = new HashMap<>(100); + } + + Object put(IFileStore key, Object value) { + keys.add(key); + return map.put(key, value); + } + + Object remove(Object key) { + keys.remove(key); + return map.remove(key); + } + + Object get(IFileStore location) { + return map.get(location); + } + + void clear() { + keys.clear(); + map.clear(); + } + + Set keys() { + return keys; + } + + SortedSet keysSubSet(IFileStore fromKey, IFileStore toKey) { + return keys.subSet(fromKey, toKey); + } + } + /** * Maintains a mapping of FileStore->IResource, such that multiple resources * mapped from the same location are tolerated. */ - class LocationMap { + private static final class LocationMap { /** * Map of FileStore->IResource OR FileStore->ArrayList of (IResource) */ - private final SortedMap map = new TreeMap<>(IFileStore::compareTo); + private final HashMapWithSortedKeys map = new HashMapWithSortedKeys(); /** * Adds the given resource to the map, keyed by the given location. @@ -177,17 +217,18 @@ public void clear() { * given location as a prefix. */ public void matchingPrefixDo(IFileStore prefix, Consumer doit) { - SortedMap matching; + Set matching; IFileStore prefixParent = prefix.getParent(); if (prefixParent != null) { //endPoint is the smallest possible path greater than the prefix that doesn't //match the prefix IFileStore endPoint = prefixParent.getChild(prefix.getName() + "\0"); //$NON-NLS-1$ - matching = map.subMap(prefix, endPoint); + matching = map.keysSubSet(prefix, endPoint); } else { - matching = map; + matching = map.keys(); } - for (Object value : matching.values()) { + for (IFileStore key : matching) { + Object value = map.get(key); if (value == null) { return; } @@ -230,11 +271,10 @@ public void matchingResourcesDo(IFileStore location, Consumer doit) { public void overLappingResourcesDo(Consumer doit) { IFileStore previousStore = null; IResource previousResource = null; - for (Entry current : map.entrySet()) { + for (IFileStore currentStore : map.keys()) { //value is either single resource or List of resources - IFileStore currentStore = current.getKey(); IResource currentResource = null; - Object value = current.getValue(); + Object value = map.get(currentStore); if (value instanceof List) { for (Object element : ((List) value)) { if (element instanceof IResource) { From 3778d568c952c8c26f35bad71dc88c4155b16ac1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 09:40:49 +0000 Subject: [PATCH 44/56] Handle long executable paths in Windows process launching Add shortenWindowsCommandLine() to shorten all command line arguments that exceed Windows MAX_PATH limit, not just the working directory. This fixes issues where Eclipse is unable to launch processes with long executable paths on Windows. The fix uses Windows GetShortPathName API via Win32Handler to convert long paths to their 8.3 short form before passing them to ProcessBuilder or Runtime.exec(). Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com> Version bump(s) for 4.38 stream --- .../org/eclipse/debug/core/DebugPlugin.java | 53 +++++++++++++++++-- .../META-INF/MANIFEST.MF | 2 +- .../debug/tests/launching/LaunchTests.java | 42 +++++++++++++-- 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java index 497aba4a8d93..06ffe1c8dd0f 100644 --- a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java @@ -1006,6 +1006,7 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env public static Process exec(String[] cmdLine, File workingDirectory, String[] envp, boolean mergeOutput) throws CoreException { List factories = DebugPlugin.getDefault().getExecFactories(); Optional directory = shortenWindowsPath(workingDirectory); + String[] shortenedCmdLine = shortenWindowsCommandLine(cmdLine); Optional> envMap = Optional.ofNullable(envp).map(array -> { Map map = new LinkedHashMap<>(); for (String e : array) { @@ -1017,7 +1018,7 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env return Map.copyOf(map); }); for (ExecFactoryFacade holder : factories) { - Optional exec = holder.exec(cmdLine.clone(), directory, envMap, mergeOutput); + Optional exec = holder.exec(shortenedCmdLine.clone(), directory, envMap, mergeOutput); if (exec.isPresent()) { return exec.get(); } @@ -1029,7 +1030,7 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env // ProcessBuilder and Runtime.exec only the new option uses process // builder to not break existing caller of this method if (mergeOutput) { - ProcessBuilder pb = new ProcessBuilder(cmdLine); + ProcessBuilder pb = new ProcessBuilder(shortenedCmdLine); directory.ifPresent(pb::directory); pb.redirectErrorStream(mergeOutput); if (envMap.isPresent()) { @@ -1039,9 +1040,9 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env } return pb.start(); } else if (directory.isEmpty()) { - return Runtime.getRuntime().exec(cmdLine, envp); + return Runtime.getRuntime().exec(shortenedCmdLine, envp); } else { - return Runtime.getRuntime().exec(cmdLine, envp, directory.get()); + return Runtime.getRuntime().exec(shortenedCmdLine, envp, directory.get()); } } catch (IOException e) { Status status = new Status(IStatus.ERROR, getUniqueIdentifier(), ERROR, DebugCoreMessages.DebugPlugin_0, e); @@ -1083,6 +1084,50 @@ private static Optional shortenWindowsPath(File path) { return Optional.ofNullable(path); } + /** + * Shortens the command line elements if they exceed Windows MAX_PATH limit. + * This is necessary because Windows process creation APIs have problems with + * long paths, even when launching executables or passing file arguments. + * + * @param cmdLine the command line array + * @return the potentially shortened command line array + */ + private static String[] shortenWindowsCommandLine(String[] cmdLine) { + if (cmdLine == null || cmdLine.length == 0 || !Platform.OS.isWindows()) { + return cmdLine; + } + + String[] result = cmdLine.clone(); + boolean modified = false; + + // Check and shorten each path-like argument in the command line + // The first element is typically the executable path, which is most critical + for (int i = 0; i < result.length; i++) { + String arg = result[i]; + if (arg != null && arg.length() > WINDOWS_MAX_PATH) { + // Check if this looks like a file path + File file = new File(arg); + if (file.isAbsolute()) { + @SuppressWarnings("restriction") + String shortPath = org.eclipse.core.internal.filesystem.local.Win32Handler.getShortPathName(arg); + if (shortPath != null) { + result[i] = shortPath; + modified = true; + if (i == 0) { + // Log only for the executable (first argument) + logDebugMessage("Shortened executable path from " + arg.length() + " to " + shortPath.length() + " characters"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } else if (i == 0) { + // Only warn for the executable path, as that's the most critical + log(Status.warning("Executable path exceeds Window's MAX_PATH limit and shortening the path failed: " + arg)); //$NON-NLS-1$ + } + } + } + } + + return modified ? result : cmdLine; + } + /** * Returns whether this plug-in is in the process of * being shutdown. diff --git a/debug/org.eclipse.debug.tests/META-INF/MANIFEST.MF b/debug/org.eclipse.debug.tests/META-INF/MANIFEST.MF index 2e9d0678fb50..9ec58f990852 100644 --- a/debug/org.eclipse.debug.tests/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.debug.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.debug.tests;singleton:=true -Bundle-Version: 3.15.100.qualifier +Bundle-Version: 3.15.200.qualifier Bundle-Localization: plugin Require-Bundle: org.eclipse.ui;bundle-version="[3.6.0,4.0.0)", org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", diff --git a/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchTests.java b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchTests.java index 07cd3af313a5..f7f2eff48e3c 100644 --- a/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchTests.java +++ b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchTests.java @@ -20,6 +20,7 @@ import java.io.BufferedReader; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; @@ -29,7 +30,9 @@ import java.util.Locale; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; +import java.util.jar.JarOutputStream; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -55,6 +58,18 @@ */ public class LaunchTests extends AbstractLaunchTest { + /** + * Windows MAX_PATH limit for file paths. See + * https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation + */ + private static final int WINDOWS_MAX_PATH = 258; + + /** + * Target length for long path tests. This should be well above MAX_PATH to + * ensure the tests exercise the long path handling code. + */ + private static final int LONG_PATH_LENGTH_TARGET = 400; + private InvocationHandler handler; private Runnable readIsTerminatedTask; private Runnable readIsDisconnectedTask; @@ -146,10 +161,10 @@ public void testProcessLaunchWithLongWorkingDirectory() throws CoreException, IO assumeTrue(Platform.OS.isWindows()); int rootLength = tempFolder.getRoot().toString().length(); - String subPathElementsName = "subfolder-with-relativly-long-name"; - String[] segments = Collections.nCopies((400 - rootLength) / subPathElementsName.length(), subPathElementsName).toArray(String[]::new); + String subPathElementsName = "subfolder-with-relatively-long-name"; + String[] segments = Collections.nCopies((LONG_PATH_LENGTH_TARGET - rootLength) / subPathElementsName.length(), subPathElementsName).toArray(String[]::new); File workingDirectory = tempFolder.newFolder(segments); - assertTrue(workingDirectory.toString().length() > 300); + assertTrue(workingDirectory.toString().length() > WINDOWS_MAX_PATH); // Just launch any process in a directory with a path longer than // Window's MAX_PATH length limit @@ -157,6 +172,27 @@ public void testProcessLaunchWithLongWorkingDirectory() throws CoreException, IO startProcessAndAssertOutputContains(List.of("java", "--version"), workingDirectory, true, "jdk"); } + @Test + public void testProcessLaunchWithLongExecutablePath() throws CoreException, IOException { + assumeTrue(Platform.OS.isWindows()); + + int rootLength = tempFolder.getRoot().toString().length(); + String subPathElementsName = "another-one-with-a-long-path-name-2"; + String[] segments = Collections.nCopies((LONG_PATH_LENGTH_TARGET - rootLength) / subPathElementsName.length(), subPathElementsName).toArray(String[]::new); + File workingDirectory = tempFolder.newFolder(segments); + assertTrue(workingDirectory.toString().length() > WINDOWS_MAX_PATH); + File jar = new File(workingDirectory, "dummy.jar"); + try (JarOutputStream stream = new JarOutputStream(new FileOutputStream(jar))) { + stream.putNextEntry(new ZipEntry("TEST")); + stream.write(1); + } + + // Just launch any process in a directory with a path longer than + // Window's MAX_PATH length limit and an argument that is even longer! + startProcessAndAssertOutputContains(List.of("java", "--version", "-cp", jar.getAbsolutePath()), workingDirectory, false, "jdk"); + startProcessAndAssertOutputContains(List.of("java", "--version", "-cp", jar.getAbsolutePath()), workingDirectory, true, "jdk"); + } + private static void startProcessAndAssertOutputContains(List cmdLine, File workingDirectory, boolean mergeOutput, String expectedOutput) throws CoreException, IOException { Process process = DebugPlugin.exec(cmdLine.toArray(String[]::new), workingDirectory, null, mergeOutput); String output; From 9dc9a9359b758f1309d5f278b0b26395cfaf783b Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 6 Nov 2025 18:47:57 +0100 Subject: [PATCH 45/56] Fix buffer overread in Win32Handler.getShortPathName causing null characters in command lines (#26) * Initial plan * Fix null character in Win32Handler.getShortPathName The issue was that GetShortPathName returns the total length of the shortened path (including prefix like \\?\), but when creating the String from the buffer with an offset, we need to use (newLength - offset) as the length parameter, not newLength. This was causing the String constructor to read past the actual data, picking up null characters from the uninitialized buffer. Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com> --- .../eclipse/core/internal/filesystem/local/Win32Handler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/Win32Handler.java b/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/Win32Handler.java index c8912f5aeac5..30405005f3f6 100644 --- a/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/Win32Handler.java +++ b/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/Win32Handler.java @@ -118,7 +118,7 @@ public static String getShortPathName(String longPath) { int newLength = com.sun.jna.platform.win32.Kernel32.INSTANCE.GetShortPathName(longPath, buffer, buffer.length); if (0 < newLength && newLength < buffer.length) { // zero means error int offset = longPath.startsWith(WIN32_UNC_RAW_PATH_PREFIX) ? WIN32_UNC_RAW_PATH_PREFIX.length() : WIN32_RAW_PATH_PREFIX.length(); - return new String(buffer, offset, newLength); + return new String(buffer, offset, newLength - offset); } return null; } From 02c4a8e95f7efc7cd9691e850f81417f6558a5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Fri, 7 Nov 2025 07:49:51 +0100 Subject: [PATCH 46/56] Improve copilot instructions and setup --- .github/copilot-instructions.md | 19 ++------------ .github/workflows/copilot-setup-steps.yml | 32 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/copilot-setup-steps.yml diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index b340544d8afd..6ecc70a3eb24 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -5,8 +5,8 @@ This repository contains the core Eclipse Platform components that form the basis for the Eclipse IDE. It is a **large-scale Java/OSGi project** (~120MB, 5,600+ Java files across 38 Maven modules) using **Maven/Tycho** for building Eclipse RCP bundles and features. **Key Technologies:** -- Language: Java (JDK 17+, targets JDK 21 in CI) -- Build: Maven 3.9+ with Eclipse Tycho (OSGi/RCP build tooling) +- Language: Java (JDK 21) +- Build: Maven 3.9.11 with Eclipse Tycho (OSGi/RCP build tooling) - Architecture: OSGi bundles organized as Eclipse plugins - Testing: JUnit with Tycho Surefire plugin @@ -22,25 +22,10 @@ This repository contains the core Eclipse Platform components that form the basi ## Critical Build Information -**⚠️ IMPORTANT: This repository CANNOT be built in isolation.** It depends on a parent POM (`eclipse-platform-parent`) from the [eclipse.platform.releng.aggregator](https://github.com/eclipse-platform/eclipse.platform.releng.aggregator) repository. - -### Individual Bundle Builds - -Individual bundles CAN be built using the pre-configured profile if you have network access to Eclipse repositories: - -```bash -cd # e.g., runtime/bundles/org.eclipse.core.runtime -mvn clean verify -Pbuild-individual-bundles -``` - The `-Pbuild-individual-bundles` profile (configured in `.mvn/maven.config`) enables the bundle to fetch the parent POM from https://repo.eclipse.org/content/repositories/eclipse/. **Note:** If network access to Eclipse repositories is blocked, individual bundle builds will fail. In such environments, code exploration and analysis can still be performed, but build verification is not possible. -### Full Platform Build - -For full platform builds, use the aggregator repository which includes this repo as a Git submodule. The CI workflows in this repository delegate to workflows in the aggregator repository. - ### Build Profiles Used in CI The Jenkinsfile shows the complete build command: diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 000000000000..51b896e1ee20 --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,32 @@ +name: "Copilot Setup Steps" + +# Automatically run the setup steps when they are changed to allow for easy validation, and +# allow manual testing through the repository's "Actions" tab +on: + workflow_dispatch: + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + +jobs: + # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. + copilot-setup-steps: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Set up Maven 3.9.11 + uses: stCarolas/setup-maven@v5 + with: + maven-version: '3.9.11' + From 7ea318542876364dd21890104006dd5bd2e2577c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 04:09:00 +0000 Subject: [PATCH 47/56] Bump actions/setup-java from 4 to 5 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/copilot-setup-steps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 51b896e1ee20..6ef3109ad671 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@v4 - name: Set up JDK 21 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: java-version: '21' distribution: 'temurin' From 5269608df223225fa86d595646c79476e5559f72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 04:09:03 +0000 Subject: [PATCH 48/56] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/copilot-setup-steps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 6ef3109ad671..c6c3f3df57bf 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -16,7 +16,7 @@ jobs: contents: read steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up JDK 21 uses: actions/setup-java@v5 From a3118c348a36222e105c3f32d2319c72d320fcef Mon Sep 17 00:00:00 2001 From: sougandhs Date: Thu, 30 Oct 2025 07:55:33 +0530 Subject: [PATCH 49/56] Fix Terminate & Remove showing every time This commit will enable Terminate and Remove option in debug view context only if there's a valid selection --- .../ui/commands/actions/TerminateAndRemoveAction.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/TerminateAndRemoveAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/TerminateAndRemoveAction.java index 496bb1c76bb5..58395322f2ea 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/TerminateAndRemoveAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/TerminateAndRemoveAction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2013 IBM Corporation and others. + * Copyright (c) 2006, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -109,7 +109,7 @@ public void debugContextChanged(DebugContextEvent event) { // enable the action, which whill just remove the terminated launches (bug 324959). fCanTerminate = !isAllTerminated; if (isAllTerminated) { - setEnabled(true); + setEnabled(!context.isEmpty()); } else { super.debugContextChanged(event); } From f1cbc1c3955ad465aee73fdbb4aca1c4596a799d Mon Sep 17 00:00:00 2001 From: sougandhs Date: Thu, 30 Oct 2025 07:37:52 +0530 Subject: [PATCH 50/56] Fix Breakpoint custom label not showing in containers This commit fixes custom breakpoint labels not being rendered in breakpoints view when breakpoints organized based on any groupings --- .../ui/model/elements/BreakpointLabelProvider.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointLabelProvider.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointLabelProvider.java index ecf6de71807a..11941d7c9b5d 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointLabelProvider.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointLabelProvider.java @@ -32,9 +32,10 @@ public class BreakpointLabelProvider extends DebugElementLabelProvider { @Override protected String getLabel(TreePath elementPath, IPresentationContext presentationContext, String columnId, int columnIndex) throws CoreException { if (columnIndex == 0) { - if (elementPath.getFirstSegment() instanceof Breakpoint breakpoint) { - if (breakpoint.getBreakpointLabel() != null) { - return breakpoint.getBreakpointLabel(); + if (elementPath.getLastSegment() instanceof Breakpoint breakpoint) { + String breakpointLabel = breakpoint.getBreakpointLabel(); + if (breakpointLabel != null) { + return breakpointLabel; } } return super.getLabel(elementPath, presentationContext, columnId, columnIndex); From 144d93448811a7cd268d191f0327bccced10a6d7 Mon Sep 17 00:00:00 2001 From: Andrey Loskutov Date: Mon, 10 Nov 2025 14:05:38 +0100 Subject: [PATCH 51/56] Breakpoint "inline editor" bugfixes and refactoring Bug fixes: - Set label background to avoid overlapping text if theming is disabled - Trim inline editor text to avoid "invisible" breakpoints - Add more space for inline editor if original labels is very short Refactoring: - perform preconditions checking at the beginning - extracted repeated dispose() code to InlineEditor.dispose() - extract Mac workaround code to dedicated method - extract editor extent calculation to dedicated method - removed useless tree.setText(current) and tree.setText("") calls - don't use syncExec to get RGB of red color Fixes https://github.com/eclipse-platform/eclipse.platform/issues/2262 --- .../breakpoints/BreakpointLabelAction.java | 168 ++++++++++-------- .../ui/views/launch/DebugElementHelper.java | 10 +- 2 files changed, 91 insertions(+), 87 deletions(-) diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/breakpoints/BreakpointLabelAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/breakpoints/BreakpointLabelAction.java index 6aac205528a4..cd4fa4071dc5 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/breakpoints/BreakpointLabelAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/breakpoints/BreakpointLabelAction.java @@ -19,7 +19,6 @@ import org.eclipse.debug.internal.ui.actions.ActionMessages; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsView; -import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; @@ -27,7 +26,6 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; @@ -37,8 +35,6 @@ import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IViewActionDelegate; import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; public class BreakpointLabelAction implements IViewActionDelegate { @@ -51,88 +47,104 @@ protected void setView(IViewPart view) { fView = view; } + private static record InlineEditor(Label label, Text text) { + void dispose() { + label.dispose(); + text.dispose(); + } + } + @Override public void run(IAction action) { - String emptyString = ""; //$NON-NLS-1$ IStructuredSelection selection = getSelection(); - - if (selection instanceof TreeSelection treeSelect && selection.getFirstElement() instanceof Breakpoint breakpoint) { - if (treeSelect.size() == 1) { - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IViewPart viewPart = page.findView(IDebugUIConstants.ID_BREAKPOINT_VIEW); - if (viewPart instanceof BreakpointsView breakpointView) { - TreeModelViewer treeViewer = breakpointView.getTreeModelViewer(); - Widget item = treeViewer.findItem(treeSelect.getPaths()[0]); - if (item instanceof TreeItem tree) { - String current = tree.getText(); - Rectangle bounds; - try { - bounds = tree.getBounds(); - } catch (ArrayIndexOutOfBoundsException e) { // TreeItem having FontData [Breakpoints having - // custom label] - tree.setFont(null); - GC gc = new GC(tree.getParent()); - Font currentFont = gc.getFont(); - gc.setFont(currentFont); - Point textWidth = gc.textExtent(tree.getText()); - gc.dispose(); - bounds = tree.getBounds(0); - bounds.x = bounds.x + 10; - bounds.width = textWidth.x + 20; - - } - Label label = new Label(tree.getParent(), SWT.WRAP); - label.setText(ActionMessages.BreakpointLabelDialog); - label.setBounds(bounds.x, bounds.y - 20, label.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, - label.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); - - Text inlineEditor = new Text(tree.getParent(), SWT.BORDER); - inlineEditor.setBounds(bounds.x, bounds.y, bounds.width, bounds.height); - inlineEditor.setText(current); - inlineEditor.selectAll(); - inlineEditor.setFocus(); - - inlineEditor.addListener(SWT.FocusOut, event -> { - tree.setText(current); - label.dispose(); - inlineEditor.dispose(); - - }); - inlineEditor.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.keyCode == SWT.ESC) { - tree.setText(current); - inlineEditor.dispose(); - label.dispose(); - } else if (e.keyCode == SWT.CR) { - String newLabel = inlineEditor.getText(); - if (!newLabel.isEmpty() && !newLabel.equals(current)) { - try { - breakpoint.setBreakpointLabel(newLabel); - } catch (CoreException e1) { - DebugUIPlugin.log(e1); - } - } else if (newLabel.isEmpty()) { - try { - breakpoint.setBreakpointLabel(null); // Set to default - } catch (CoreException e2) { - DebugUIPlugin.log(e2); - } - } - inlineEditor.dispose(); - label.dispose(); - } - } - }); - tree.setText(emptyString); - + if (!(selection instanceof TreeSelection treeSelect) + || treeSelect.size() != 1 + || !(selection.getFirstElement() instanceof Breakpoint breakpoint) + || !(fView instanceof BreakpointsView breakpointView)) { + return; + } + TreeModelViewer treeViewer = breakpointView.getTreeModelViewer(); + Widget item = treeViewer.findItem(treeSelect.getPaths()[0]); + if (!(item instanceof TreeItem treeItem)) { + return; + } + Rectangle editorBounds = computeInlineEditorBounds(treeItem); + + Label label = new Label(treeItem.getParent(), SWT.WRAP); + label.setText(ActionMessages.BreakpointLabelDialog); + Point defaultLabelSize = label.computeSize(SWT.DEFAULT, SWT.DEFAULT); + label.setBounds(editorBounds.x, editorBounds.y - 20, defaultLabelSize.x, defaultLabelSize.y); + label.setBackground(treeItem.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + + String current = treeItem.getText(); + Text textEditor = new Text(treeItem.getParent(), SWT.BORDER); + textEditor.setBounds(editorBounds.x, editorBounds.y, editorBounds.width, editorBounds.height); + textEditor.setText(current); + textEditor.selectAll(); + textEditor.setFocus(); + + final InlineEditor inlineEditor = new InlineEditor(label, textEditor); + textEditor.addListener(SWT.FocusOut, event -> inlineEditor.dispose()); + textEditor.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.keyCode == SWT.ESC) { + inlineEditor.dispose(); + } else if (e.keyCode == SWT.CR) { + String newLabel = textEditor.getText().strip(); + if (newLabel.equals(current)) { + inlineEditor.dispose(); + return; } - + if (newLabel.isEmpty()) { + newLabel = null; // reset to default breakpoint label + } + try { + breakpoint.setBreakpointLabel(newLabel); + } catch (CoreException e1) { + DebugUIPlugin.log(e1); + } + inlineEditor.dispose(); } } + }); + } + + private static Rectangle computeInlineEditorBounds(TreeItem treeItem) { + Rectangle bounds; + try { + bounds = treeItem.getBounds(); + } catch (ArrayIndexOutOfBoundsException e) { + // TreeItem having FontData [Breakpoints having custom label] + bounds = macBugWorkaround(treeItem); } + int editorWidth = Math.max(computeEditorExtent(treeItem), bounds.width); + return new Rectangle(bounds.x, bounds.y, editorWidth, bounds.height); + } + + // Workaround for SWT bug on Mac where TreeItem.getBounds() throws exception + // when custom fonts are used, see + // https://github.com/eclipse-platform/eclipse.platform.swt/issues/2749 + private static Rectangle macBugWorkaround(TreeItem treeItem) { + treeItem.setFont(null); + Rectangle bounds = treeItem.getBounds(0); + bounds.x = bounds.x + 10; + bounds.width = computeEditorExtent(treeItem); + return bounds; + } + private static int computeEditorExtent(TreeItem treeItem) { + GC gc = new GC(treeItem.getParent()); + try { + Point textWidth = gc.textExtent(treeItem.getText()); + // Editor needs space on both sides around text + int width = textWidth.x + 20; + // Give editor more room to grow for new text + width = Math.max(100, width); + return width; + } finally { + gc.dispose(); + } } protected IStructuredSelection getSelection() { diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java index b9de9b753dad..7798cf93f666 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java @@ -30,7 +30,6 @@ import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Display; /** * Translates images, colors, and fonts into image descriptors, RGBs, and font @@ -146,14 +145,7 @@ public static RGB getForeground(Object element, IDebugModelPresentation presenta if (element instanceof Breakpoint breakpoint) { if (breakpoint.getBreakpointLabel() != null) { - final RGB[] rgb = new RGB[1]; - Display.getDefault().syncExec(() -> { - Color redColor = Display.getDefault().getSystemColor(SWT.COLOR_RED); - rgb[0] = redColor.getRGB(); - }); - if (rgb[0] != null) { - return rgb[0]; - } + return new RGB(255, 0, 0); } return null; } From 39dbe3c1721898ea1ca1469b1d4f8c904da1c164 Mon Sep 17 00:00:00 2001 From: Ed Merks Date: Tue, 11 Nov 2025 13:00:50 +0100 Subject: [PATCH 52/56] Use eclipse32.svg for the branding image not eclipse32.png https://github.com/eclipse-platform/eclipse.platform/issues/2261 --- platform/org.eclipse.platform/about.ini | 2 +- platform/org.eclipse.sdk/about.ini | 2 +- .../about.ini | 2 +- .../build.properties | 9 +- .../eclipse32.png | Bin 2233 -> 0 bytes .../eclipse32.svg | 234 ++++++++++++++++++ .../bundles/org.eclipse.core.tools/about.ini | 2 +- .../org.eclipse.core.tools/build.properties | 3 +- .../org.eclipse.core.tools/eclipse32.svg | 234 ++++++++++++++++++ ua/org.eclipse.help.base/about.ini | 2 +- ua/org.eclipse.help.base/build.properties | 4 +- ua/org.eclipse.help.base/eclipse32.png | Bin 2233 -> 0 bytes ua/org.eclipse.help.base/eclipse32.svg | 234 ++++++++++++++++++ 13 files changed, 719 insertions(+), 9 deletions(-) delete mode 100644 resources/bundles/org.eclipse.core.tools.resources/eclipse32.png create mode 100644 resources/bundles/org.eclipse.core.tools.resources/eclipse32.svg create mode 100644 runtime/bundles/org.eclipse.core.tools/eclipse32.svg delete mode 100644 ua/org.eclipse.help.base/eclipse32.png create mode 100644 ua/org.eclipse.help.base/eclipse32.svg diff --git a/platform/org.eclipse.platform/about.ini b/platform/org.eclipse.platform/about.ini index 167f5068a6cc..750bf909d4a1 100644 --- a/platform/org.eclipse.platform/about.ini +++ b/platform/org.eclipse.platform/about.ini @@ -9,7 +9,7 @@ aboutText=%blurb # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.png +featureImage=eclipse32.svg # Property "welcomePage" contains path to welcome page (special XML-based format) # ($nl$/ prefix to permit locale-specific translations of entire file) diff --git a/platform/org.eclipse.sdk/about.ini b/platform/org.eclipse.sdk/about.ini index 188896b22e17..2263d0a7603c 100644 --- a/platform/org.eclipse.sdk/about.ini +++ b/platform/org.eclipse.sdk/about.ini @@ -11,7 +11,7 @@ aboutText=%blurb # needed for primary features only # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.png +featureImage=eclipse32.svg # Property "aboutImage" contains path to product image (500x330 or 115x164) # needed for primary features only diff --git a/resources/bundles/org.eclipse.core.tools.resources/about.ini b/resources/bundles/org.eclipse.core.tools.resources/about.ini index 34870781b241..130e80d1ed72 100644 --- a/resources/bundles/org.eclipse.core.tools.resources/about.ini +++ b/resources/bundles/org.eclipse.core.tools.resources/about.ini @@ -11,7 +11,7 @@ aboutText=%blurb # needed for primary features only # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.png +featureImage=eclipse32.svg # Property "aboutImage" contains path to product image (500x330 or 115x164) # needed for primary features only diff --git a/resources/bundles/org.eclipse.core.tools.resources/build.properties b/resources/bundles/org.eclipse.core.tools.resources/build.properties index dfac95d38252..f46098951ce6 100644 --- a/resources/bundles/org.eclipse.core.tools.resources/build.properties +++ b/resources/bundles/org.eclipse.core.tools.resources/build.properties @@ -14,5 +14,12 @@ source.. = src/ output.. = bin/ src.includes=*.html -bin.includes=plugin.xml,icons/,doc/,*.html,.options, META-INF/,. +bin.includes = plugin.xml,\ + icons/,\ + doc/,\ + *.html,\ + .options,\ + META-INF/,\ + .,\ + eclipse32.svg qualifier=context diff --git a/resources/bundles/org.eclipse.core.tools.resources/eclipse32.png b/resources/bundles/org.eclipse.core.tools.resources/eclipse32.png deleted file mode 100644 index bf856800755a9452f85c8d5948adf5334706c8f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2233 zcmbVOX;c&E8Xl0XAc&}-h!O${qFE*@nUY{gf&>X=Q=kZ#Wq=6D#AJX#3tpCjQiUrD z7cju7B2@5zQl(V3iXfus<+_wALS?C3mqH6F_260dJw?5jyjdxkA*P(e5vg2bXJVl@nKWrzgE2^HcvI2abo zQup@3o&c~!DGv=t!$tm(6j2bxdL5!xp~BDr;OV7RiKPiJij%-`awQu--P(!A$z^PO z7+pjbsd#X_+&4`Phol9BO4AagEE(R5gY(ov7=Z#t#W<}ZQK^BnZ2UW32;1wANqF2l z6*Pg3fA3VdC=ka()G&@tBom}$1{ucyi6E86WHPtlC}faKB2!2pg#a=kDg`2waSIO~ zv!<5CLcx5W1zVWJ#>bL0~+BBAR$a zh2w?LaU!u)uGGu=61|U@53A+Lu*^q|C~)s`49P!YpXx*BQfX8HPk=e^0fHWUZ*MM* z!sqko6dsLB!7pHC|8L$%m_sCell)K9EFNKUlG&z&dBlbVax0 zg{0$N{6{9w^RmtvbHCX={$^>nWHRNGvnYln4~Q=-O+#P(Zv$wuD1B~=g6ObdmLe$s|WmR8&A9(Xz_}h z_%Y9G0}zIsls1N$4j-9sb92qA+h`Lwp6_O|el-Ba?p@>U40Q4KRc9lG4QG^-naVJM zb7(O$@z0>3hnaR$TPfdJmmCfCGF(G62cUg+|1eN@lnxk1#dLc%{d7Aj?6up^iW|qh z+jP3z__3Y7cdDa}Z0^|rkZbFUBeQ2u^`9J>zS&Vze&Y14p!pwDOLiDcU4D~wuz&91 zwoA=rv&_!gSJ%&Pvv+Lbvkx3LD@wSBPW3(1SvRzM1uzHElKU)Hc|w7N@4!2FX_WQqO4$ye zMsq^PnU7e#H>|m`L3R77-}pD+y7>esJpcGF)ZpDy8F$+p>t5rE<-_yOz_n4$_3Ows zRsPl0Zr5bOZ3Pb$FRxy-o$gHxS=+KJ;0##raMI13(5Xdd9p7Flzjd>3mUd{mbY*0^ ziRc#h4(*D}MMe5oLnm^uY6B1;i+Q@X_}UjYI)KJ!ZAOLc5tDO=Mv8}BR~Wv6I0o#- z*U9DJrxo0e)aZoauwTqHDYj0u z|5+>h8t=%~f?2uU5lz*TjE8q0&;7F^+qLbt2gzXuf*D`MTT^P4=~q+rkKIjc-d1Ec znsgdi00ong$gs|sYi(%*IVAfp3Ar%v#N9BE>kIE5jdqZnU1b3}$ju9WpJdzC7v@ zv#eZ_o!(StUr~6!XCS5P;)^9d_6+wP?_lNTj=!h)8drlo+qZ-J`BNerV09L|eo$rpEDKq)E%Yo4!8TW7&L&S9z2Z~Ol%F#@yr{dT0Y@y z+7jN;YoWo(N=&TioKBrcwU1$*?yBR|rtdX+t~;MTw(aJaI_SnKks*f_C+C!JyoBG! zJ}7gzV&{@$DrIHm2)JX{2aT4780@%_9$r}~x+(&k+GRlV&dfwJo1?MoBGP?-6*gJ4 z=v*h=T1jkX>F?j)X8*d$#oza9;$}@|MTFfc_n$mQzpnE$_ETN|L11TVbJB&zUv+6h z=lSJ~`sPqe?~`HwTqMc5Y<)!K7=*yBO z)`Hr=lE(Wk?YSPy>^?2kF^w%!o;!lS&wQ`z-7)f@zU!hdIoi;Y3P_+ h%lPOsapB}!3o?-0Ch6$S^m+F;Aru7g8@zXC{RfC%fX@H` diff --git a/resources/bundles/org.eclipse.core.tools.resources/eclipse32.svg b/resources/bundles/org.eclipse.core.tools.resources/eclipse32.svg new file mode 100644 index 000000000000..4f0e95ebbf35 --- /dev/null +++ b/resources/bundles/org.eclipse.core.tools.resources/eclipse32.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/runtime/bundles/org.eclipse.core.tools/about.ini b/runtime/bundles/org.eclipse.core.tools/about.ini index f893efd31f24..130e80d1ed72 100644 --- a/runtime/bundles/org.eclipse.core.tools/about.ini +++ b/runtime/bundles/org.eclipse.core.tools/about.ini @@ -11,7 +11,7 @@ aboutText=%blurb # needed for primary features only # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.gif +featureImage=eclipse32.svg # Property "aboutImage" contains path to product image (500x330 or 115x164) # needed for primary features only diff --git a/runtime/bundles/org.eclipse.core.tools/build.properties b/runtime/bundles/org.eclipse.core.tools/build.properties index b0d9780d0bbe..561ae6d5e003 100644 --- a/runtime/bundles/org.eclipse.core.tools/build.properties +++ b/runtime/bundles/org.eclipse.core.tools/build.properties @@ -23,5 +23,6 @@ bin.includes = plugin.xml,\ plugin.properties,\ about.ini,\ about.mappings,\ - about.properties + about.properties,\ + eclipse32.svg qualifier=context diff --git a/runtime/bundles/org.eclipse.core.tools/eclipse32.svg b/runtime/bundles/org.eclipse.core.tools/eclipse32.svg new file mode 100644 index 000000000000..4f0e95ebbf35 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.tools/eclipse32.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/ua/org.eclipse.help.base/about.ini b/ua/org.eclipse.help.base/about.ini index 76a035608c3a..ff2b3fa15ccf 100644 --- a/ua/org.eclipse.help.base/about.ini +++ b/ua/org.eclipse.help.base/about.ini @@ -11,7 +11,7 @@ aboutText=%blurb # needed for primary features only # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.png +featureImage=eclipse32.svg # Property "aboutImage" contains path to product image (500x330 or 115x164) # needed for primary features only diff --git a/ua/org.eclipse.help.base/build.properties b/ua/org.eclipse.help.base/build.properties index b1323e48594e..9a997796f13b 100644 --- a/ua/org.eclipse.help.base/build.properties +++ b/ua/org.eclipse.help.base/build.properties @@ -24,9 +24,9 @@ bin.includes = doc/,\ about.ini,\ about.mappings,\ about.properties,\ - eclipse32.png,\ META-INF/,\ - ant_tasks/helpbase-ant.jar + ant_tasks/helpbase-ant.jar,\ + eclipse32.svg jars.compile.order = .,\ ant_tasks/helpbase-ant.jar diff --git a/ua/org.eclipse.help.base/eclipse32.png b/ua/org.eclipse.help.base/eclipse32.png deleted file mode 100644 index bf856800755a9452f85c8d5948adf5334706c8f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2233 zcmbVOX;c&E8Xl0XAc&}-h!O${qFE*@nUY{gf&>X=Q=kZ#Wq=6D#AJX#3tpCjQiUrD z7cju7B2@5zQl(V3iXfus<+_wALS?C3mqH6F_260dJw?5jyjdxkA*P(e5vg2bXJVl@nKWrzgE2^HcvI2abo zQup@3o&c~!DGv=t!$tm(6j2bxdL5!xp~BDr;OV7RiKPiJij%-`awQu--P(!A$z^PO z7+pjbsd#X_+&4`Phol9BO4AagEE(R5gY(ov7=Z#t#W<}ZQK^BnZ2UW32;1wANqF2l z6*Pg3fA3VdC=ka()G&@tBom}$1{ucyi6E86WHPtlC}faKB2!2pg#a=kDg`2waSIO~ zv!<5CLcx5W1zVWJ#>bL0~+BBAR$a zh2w?LaU!u)uGGu=61|U@53A+Lu*^q|C~)s`49P!YpXx*BQfX8HPk=e^0fHWUZ*MM* z!sqko6dsLB!7pHC|8L$%m_sCell)K9EFNKUlG&z&dBlbVax0 zg{0$N{6{9w^RmtvbHCX={$^>nWHRNGvnYln4~Q=-O+#P(Zv$wuD1B~=g6ObdmLe$s|WmR8&A9(Xz_}h z_%Y9G0}zIsls1N$4j-9sb92qA+h`Lwp6_O|el-Ba?p@>U40Q4KRc9lG4QG^-naVJM zb7(O$@z0>3hnaR$TPfdJmmCfCGF(G62cUg+|1eN@lnxk1#dLc%{d7Aj?6up^iW|qh z+jP3z__3Y7cdDa}Z0^|rkZbFUBeQ2u^`9J>zS&Vze&Y14p!pwDOLiDcU4D~wuz&91 zwoA=rv&_!gSJ%&Pvv+Lbvkx3LD@wSBPW3(1SvRzM1uzHElKU)Hc|w7N@4!2FX_WQqO4$ye zMsq^PnU7e#H>|m`L3R77-}pD+y7>esJpcGF)ZpDy8F$+p>t5rE<-_yOz_n4$_3Ows zRsPl0Zr5bOZ3Pb$FRxy-o$gHxS=+KJ;0##raMI13(5Xdd9p7Flzjd>3mUd{mbY*0^ ziRc#h4(*D}MMe5oLnm^uY6B1;i+Q@X_}UjYI)KJ!ZAOLc5tDO=Mv8}BR~Wv6I0o#- z*U9DJrxo0e)aZoauwTqHDYj0u z|5+>h8t=%~f?2uU5lz*TjE8q0&;7F^+qLbt2gzXuf*D`MTT^P4=~q+rkKIjc-d1Ec znsgdi00ong$gs|sYi(%*IVAfp3Ar%v#N9BE>kIE5jdqZnU1b3}$ju9WpJdzC7v@ zv#eZ_o!(StUr~6!XCS5P;)^9d_6+wP?_lNTj=!h)8drlo+qZ-J`BNerV09L|eo$rpEDKq)E%Yo4!8TW7&L&S9z2Z~Ol%F#@yr{dT0Y@y z+7jN;YoWo(N=&TioKBrcwU1$*?yBR|rtdX+t~;MTw(aJaI_SnKks*f_C+C!JyoBG! zJ}7gzV&{@$DrIHm2)JX{2aT4780@%_9$r}~x+(&k+GRlV&dfwJo1?MoBGP?-6*gJ4 z=v*h=T1jkX>F?j)X8*d$#oza9;$}@|MTFfc_n$mQzpnE$_ETN|L11TVbJB&zUv+6h z=lSJ~`sPqe?~`HwTqMc5Y<)!K7=*yBO z)`Hr=lE(Wk?YSPy>^?2kF^w%!o;!lS&wQ`z-7)f@zU!hdIoi;Y3P_+ h%lPOsapB}!3o?-0Ch6$S^m+F;Aru7g8@zXC{RfC%fX@H` diff --git a/ua/org.eclipse.help.base/eclipse32.svg b/ua/org.eclipse.help.base/eclipse32.svg new file mode 100644 index 000000000000..4f0e95ebbf35 --- /dev/null +++ b/ua/org.eclipse.help.base/eclipse32.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + From ef7ee802d43d5637f15822b83530d2fcfe4e9763 Mon Sep 17 00:00:00 2001 From: Sebastian Ratz Date: Mon, 3 Nov 2025 17:10:31 +0000 Subject: [PATCH 53/56] Use a merged JVM+OS trust store as default SSLContext Merge JVM and OS trust stores in case opt-in system property eclipse.platform.mergeTrust is set and trust is not otherwise customized via the javax.net.ssl.trustStore[...] system properties. Resolves: https://bugs.eclipse.org/bugs/show_bug.cgi?id=567504 https://github.com/eclipse-platform/eclipse.platform/issues/1690 Obsoletes (to-be-reverted): https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/pull/929 https://github.com/eclipse-packaging/packages/pull/224 Replaces: https://github.com/eclipse-equinox/equinox/pull/1176 See also: https://github.com/eclipse-simrel/.github/pull/38 --- .../runtime/CollectionTrustManager.java | 82 +++++ .../internal/runtime/InternalPlatform.java | 10 + .../core/internal/runtime/KeyStoreUtil.java | 160 +++++++++ .../META-INF/MANIFEST.MF | 1 + .../runtime/AllInternalRuntimeTests.java | 2 + .../runtime/CollectionTrustManagerTest.java | 275 +++++++++++++++ .../internal/runtime/KeyStoreUtilTest.java | 328 ++++++++++++++++++ .../core/tests/internal/runtime/keystore.p12 | Bin 0 -> 2472 bytes .../tests/internal/runtime/truststore.jks | Bin 0 -> 764 bytes 9 files changed, 858 insertions(+) create mode 100644 runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/CollectionTrustManager.java create mode 100644 runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/KeyStoreUtil.java create mode 100644 runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/CollectionTrustManagerTest.java create mode 100644 runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/KeyStoreUtilTest.java create mode 100644 runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/keystore.p12 create mode 100644 runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/truststore.jks diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/CollectionTrustManager.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/CollectionTrustManager.java new file mode 100644 index 000000000000..e0e41f49f918 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/CollectionTrustManager.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import javax.net.ssl.X509TrustManager; + +public class CollectionTrustManager implements X509TrustManager { + + private final List trustManagers; + + public CollectionTrustManager(List trustManagers) { + this.trustManagers = trustManagers; + } + + public List getTrustManagers() { + return trustManagers; + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + CertificateException ce = null; + for (X509TrustManager trustManager : this.getTrustManagers()) { + try { + trustManager.checkClientTrusted(chain, authType); + return; + } catch (CertificateException e) { + if (ce == null) { + ce = e; + } else { + ce.addSuppressed(e); + } + } + } + if (ce != null) { + throw ce; + } + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + CertificateException ce = null; + for (X509TrustManager trustManager : this.getTrustManagers()) { + try { + trustManager.checkServerTrusted(chain, authType); + return; + } catch (CertificateException e) { + if (ce == null) { + ce = e; + } else { + ce.addSuppressed(e); + } + } + } + if (ce != null) { + throw ce; + } + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return this.getTrustManagers().stream() // + .map(X509TrustManager::getAcceptedIssuers) // + .filter(Objects::nonNull).flatMap(Arrays::stream).toArray(X509Certificate[]::new); + } + +} diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java index 990d7d3c9cf3..7148f259a8d0 100644 --- a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java @@ -48,6 +48,7 @@ import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.RegistryFactory; import org.eclipse.core.runtime.ServiceCaller; +import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.content.IContentTypeManager; import org.eclipse.core.runtime.preferences.IPreferencesService; import org.eclipse.equinox.app.IApplicationContext; @@ -585,6 +586,14 @@ private void initializeAuthorizationHandler() { } } + private void initializeSSLContext() { + try { + new KeyStoreUtil(getOS()).setUpSslContext(); + } catch (Exception e) { + RuntimeLog.log(Status.error("Exception setting up SSLContext", e)); //$NON-NLS-1$ + } + } + /* * Finds and loads the options file */ @@ -701,6 +710,7 @@ public void start(BundleContext runtimeContext) { initialized = true; stopped = false; initializeAuthorizationHandler(); + initializeSSLContext(); startServices(); } diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/KeyStoreUtil.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/KeyStoreUtil.java new file mode 100644 index 000000000000..20299109d482 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/KeyStoreUtil.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509KeyManager; +import javax.net.ssl.X509TrustManager; +import org.eclipse.osgi.service.environment.Constants; + +public class KeyStoreUtil { + + @SuppressWarnings("nls") + private static final String SYSTEM_PROPERTY_MERGE_TRUST = "eclipse.platform.mergeTrust"; + + private final String os; + + private static final record KeyStoreAndPassword(KeyStore keyStore, char[] password) { + } + + public KeyStoreUtil(String os) { + this.os = os; + } + + @SuppressWarnings("nls") + public void setUpSslContext() throws GeneralSecurityException, IOException { + + if (!Boolean.getBoolean(SYSTEM_PROPERTY_MERGE_TRUST)) { + return; + } + + List keyStores = new ArrayList<>(); + // null will loads JVM cacerts OR store indicated by "javax.net.ssl.trustStore" properties + keyStores.add(new KeyStoreAndPassword(null, null)); + if (System.getProperty("javax.net.ssl.trustStore", "").isEmpty()) { + if (Constants.OS_MACOSX.equals(os)) { + keyStores.add(createKeyStore("KeychainStore", "Apple")); + } else if (Constants.OS_WIN32.equals(os)) { + keyStores.add(createKeyStore("Windows-ROOT", null)); + } + } + List trustManagers = new ArrayList<>(); + for (KeyStoreAndPassword storeAndPassword : keyStores) { + trustManagers.add(createX509TrustManager(storeAndPassword.keyStore())); + } + TrustManager[] tm = { new CollectionTrustManager(trustManagers) }; + + KeyManager[] km = {}; + KeyStoreAndPassword keyStore = createKeyStoreFromSystemProperties(); + if (keyStore != null) { + km = new KeyManager[] { createX509KeyManager(keyStore.keyStore(), keyStore.password()) }; + } + + SSLContext sslContext = SSLContext.getInstance("TLS"); + initSSLContext(sslContext, tm, km, null); + SSLContext.setDefault(sslContext); + } + + private KeyStoreAndPassword createKeyStore(String type, String provider) + throws GeneralSecurityException, IOException { + KeyStore keyStore; + if (provider == null) { + keyStore = KeyStore.getInstance(type); + } else { + keyStore = KeyStore.getInstance(type, provider); + } + keyStore.load(null, null); + return new KeyStoreAndPassword(keyStore, null); + } + + protected X509TrustManager createX509TrustManager(KeyStore keyStore) throws GeneralSecurityException { + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); + return Arrays.stream(tmf.getTrustManagers()).filter(X509TrustManager.class::isInstance) // + .map(X509TrustManager.class::cast) // + .findFirst().orElse(null); + } + + protected X509KeyManager createX509KeyManager(KeyStore keyStore, char[] password) throws GeneralSecurityException { + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, password); + return Arrays.stream(kmf.getKeyManagers()).filter(X509KeyManager.class::isInstance) // + .map(X509KeyManager.class::cast) // + .findFirst().orElse(null); + } + + protected void initSSLContext(SSLContext context, TrustManager[] trustManagers, KeyManager[] keyManagers, + SecureRandom random) throws KeyManagementException { + context.init(keyManagers, trustManagers, random); + } + + /** + * Coding based on + * sun.security.ssl.SSLContextImpl.DefaultManagersHolder.getKeyManagers() with + * minor adjustments (access properties directy without AccessController, return + * nothing if properties not set). + */ + @SuppressWarnings("nls") + private KeyStoreAndPassword createKeyStoreFromSystemProperties() throws GeneralSecurityException, IOException { + String p11KeyStore = "PKCS11"; + String none = "NONE"; + String keyStore = System.getProperty("javax.net.ssl.keyStore", ""); + String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType", ""); + String keyStoreProvider = System.getProperty("javax.net.ssl.keyStoreProvider", ""); + String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword", ""); + + if (keyStoreType.isEmpty()) { + if (keyStore.isEmpty()) { + return null; + } + keyStoreType = KeyStore.getDefaultType(); + } + if (p11KeyStore.equals(keyStoreType) && !none.equals(keyStore)) { + throw new IllegalArgumentException("if keyStoreType is " + p11KeyStore + ", then keyStore must be " + none); + } + char[] passwd = null; + if (!keyStorePassword.isEmpty()) { + passwd = keyStorePassword.toCharArray(); + } + KeyStore ks = null; + if (keyStoreProvider.isEmpty()) { + ks = KeyStore.getInstance(keyStoreType); + } else { + ks = KeyStore.getInstance(keyStoreType, keyStoreProvider); + } + if (!keyStore.isEmpty() && !none.equals(keyStore)) { + try (InputStream is = new FileInputStream(keyStore)) { + ks.load(is, passwd); + } + } else { + ks.load(null, passwd); + } + return new KeyStoreAndPassword(ks, p11KeyStore.equals(keyStoreType) ? null : passwd); + } + +} diff --git a/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF index 96503cbe97d3..2487c0c862b4 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF @@ -16,6 +16,7 @@ Require-Bundle: org.junit, org.eclipse.core.tests.harness;bundle-version="3.11.0" Import-Package: org.assertj.core.api, org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.condition;version="[5.14.0,6.0.0)", org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", org.junit.jupiter.api.io;version="[5.14.0,6.0.0)", diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java index 765014a6b7a5..57bff2dcc338 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java @@ -18,6 +18,8 @@ @Suite @SelectClasses({ // + CollectionTrustManagerTest.class, // + KeyStoreUtilTest.class, // LogSerializationTest.class, // PlatformURLLocalTest.class, // PlatformURLSessionTest.class }) diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/CollectionTrustManagerTest.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/CollectionTrustManagerTest.java new file mode 100644 index 000000000000..ac5c36feb969 --- /dev/null +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/CollectionTrustManagerTest.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.tests.internal.runtime; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.arrayContaining; +import static org.hamcrest.Matchers.sameInstance; +import static org.junit.Assert.assertThrows; + +import java.math.BigInteger; +import java.security.Principal; +import java.security.PublicKey; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Set; +import javax.net.ssl.X509TrustManager; +import org.eclipse.core.internal.runtime.CollectionTrustManager; +import org.junit.Test; + +@SuppressWarnings("restriction") +public class CollectionTrustManagerTest { + + @Test + public void testAcceptedIssuers() throws Exception { + X509Certificate[] acceptedIssuers1 = { new StubX509Certificate(), new StubX509Certificate() }; + X509Certificate[] acceptedIssuers2 = { new StubX509Certificate(), new StubX509Certificate() }; + X509TrustManager manager1 = new StubX509TrustManager(List.of(acceptedIssuers1)); + X509TrustManager manager2 = new StubX509TrustManager(List.of(acceptedIssuers2)); + CollectionTrustManager collectionTrustManager = new CollectionTrustManager(Arrays.asList(manager1, manager2)); + + X509Certificate[] allAcceptedIssuers = collectionTrustManager.getAcceptedIssuers(); + + assertThat(allAcceptedIssuers, + arrayContaining(acceptedIssuers1[0], acceptedIssuers1[1], acceptedIssuers2[0], acceptedIssuers2[1])); + } + + @Test + public void testCheckClientTrusted() throws Exception { + X509Certificate[] chainTrustedBy1 = { new StubX509Certificate() }; + X509Certificate[] chainTrustedBy2 = { new StubX509Certificate() }; + X509Certificate[] chainTrustedByNone = { new StubX509Certificate() }; + X509Certificate[] chainTrustedByBoth = { new StubX509Certificate() }; + String authType = "testAuthType"; + + StubX509TrustManager manager1 = new StubX509TrustManager(List.of(chainTrustedBy1, chainTrustedByBoth)); + StubX509TrustManager manager2 = new StubX509TrustManager(List.of(chainTrustedBy2, chainTrustedByBoth)); + + CollectionTrustManager collectionTrustManager = new CollectionTrustManager(Arrays.asList(manager1, manager2)); + + collectionTrustManager.checkClientTrusted(chainTrustedBy1, authType); + collectionTrustManager.checkClientTrusted(chainTrustedBy2, authType); + collectionTrustManager.checkClientTrusted(chainTrustedByBoth, authType); + + CertificateException exception = assertThrows(CertificateException.class, () -> { + collectionTrustManager.checkClientTrusted(chainTrustedByNone, authType); + }); + assertThat(exception, sameInstance(manager1.exception)); // first in the list + assertThat(exception.getSuppressed(), arrayContaining(sameInstance(manager2.exception))); // second, suppressed + } + + @Test + public void testCheckServerTrusted() throws Exception { + X509Certificate[] chainTrustedBy1 = { new StubX509Certificate() }; + X509Certificate[] chainTrustedBy2 = { new StubX509Certificate() }; + X509Certificate[] chainTrustedByNone = { new StubX509Certificate() }; + X509Certificate[] chainTrustedByBoth = { new StubX509Certificate() }; + String authType = "testAuthType"; + + StubX509TrustManager manager1 = new StubX509TrustManager(List.of(chainTrustedBy1, chainTrustedByBoth)); + StubX509TrustManager manager2 = new StubX509TrustManager(List.of(chainTrustedBy2, chainTrustedByBoth)); + + CollectionTrustManager collectionTrustManager = new CollectionTrustManager(Arrays.asList(manager1, manager2)); + + collectionTrustManager.checkServerTrusted(chainTrustedBy1, authType); + collectionTrustManager.checkServerTrusted(chainTrustedBy2, authType); + collectionTrustManager.checkServerTrusted(chainTrustedByBoth, authType); + + CertificateException exception = assertThrows(CertificateException.class, () -> { + collectionTrustManager.checkServerTrusted(chainTrustedByNone, authType); + }); + assertThat(exception, sameInstance(manager1.exception)); // first in the list + assertThat(exception.getSuppressed(), arrayContaining(sameInstance(manager2.exception))); // second, suppressed + } + + private static class StubX509TrustManager implements X509TrustManager { + + public final CertificateException exception = new CertificateException(); + private List trusted; + + public StubX509TrustManager(List trusted) { + this.trusted = trusted; + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + for (X509Certificate[] trustedChain : trusted) { + if (Arrays.equals(chain, trustedChain)) { + return; + } + } + throw exception; + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + for (X509Certificate[] trustedChain : trusted) { + if (Arrays.equals(chain, trustedChain)) { + return; + } + } + throw exception; + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return trusted.stream().flatMap(Arrays::stream).toArray(X509Certificate[]::new); + } + + } + + private static class StubX509Certificate extends X509Certificate { + + @Override + public boolean hasUnsupportedCriticalExtension() { + throw new IllegalStateException(); + } + + @Override + public Set getCriticalExtensionOIDs() { + throw new IllegalStateException(); + } + + @Override + public Set getNonCriticalExtensionOIDs() { + throw new IllegalStateException(); + } + + @Override + public byte[] getExtensionValue(String oid) { + throw new IllegalStateException(); + } + + @Override + public void checkValidity() { + throw new IllegalStateException(); + } + + @Override + public void checkValidity(Date date) { + throw new IllegalStateException(); + } + + @Override + public int getVersion() { + throw new IllegalStateException(); + } + + @Override + public BigInteger getSerialNumber() { + throw new IllegalStateException(); + } + + @SuppressWarnings("deprecation") + @Override + public Principal getIssuerDN() { + throw new IllegalStateException(); + } + + @SuppressWarnings("deprecation") + @Override + public Principal getSubjectDN() { + throw new IllegalStateException(); + } + + @Override + public Date getNotBefore() { + throw new IllegalStateException(); + } + + @Override + public Date getNotAfter() { + throw new IllegalStateException(); + } + + @Override + public byte[] getTBSCertificate() { + throw new IllegalStateException(); + } + + @Override + public byte[] getSignature() { + throw new IllegalStateException(); + } + + @Override + public String getSigAlgName() { + throw new IllegalStateException(); + } + + @Override + public String getSigAlgOID() { + throw new IllegalStateException(); + } + + @Override + public byte[] getSigAlgParams() { + throw new IllegalStateException(); + } + + @Override + public boolean[] getIssuerUniqueID() { + throw new IllegalStateException(); + } + + @Override + public boolean[] getSubjectUniqueID() { + throw new IllegalStateException(); + } + + @Override + public boolean[] getKeyUsage() { + throw new IllegalStateException(); + } + + @Override + public int getBasicConstraints() { + throw new IllegalStateException(); + } + + @Override + public byte[] getEncoded() { + throw new IllegalStateException(); + } + + @Override + public void verify(PublicKey key) { + throw new IllegalStateException(); + } + + @Override + public void verify(PublicKey key, String sigProvider) { + throw new IllegalStateException(); + } + + @Override + public PublicKey getPublicKey() { + throw new IllegalStateException(); + } + + @Override + public String toString() { + return Integer.toHexString(System.identityHashCode(this)); + } + + @Override + public boolean equals(Object other) { + return other == this; + } + + } +} diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/KeyStoreUtilTest.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/KeyStoreUtilTest.java new file mode 100644 index 000000000000..86409911337a --- /dev/null +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/KeyStoreUtilTest.java @@ -0,0 +1,328 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.tests.internal.runtime; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.arrayWithSize; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.matchesRegex; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509KeyManager; +import javax.net.ssl.X509TrustManager; +import javax.security.auth.x500.X500Principal; +import org.eclipse.core.internal.runtime.CollectionTrustManager; +import org.eclipse.core.internal.runtime.KeyStoreUtil; +import org.eclipse.core.runtime.Platform; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; +import org.junit.jupiter.api.io.TempDir; + +@SuppressWarnings("restriction") +public class KeyStoreUtilTest { + + private static final List SYSTEM_PROPERTIES_TO_BACKUP_AND_RESTORE = List.of( // + "eclipse.platform.mergeTrust", // + "javax.net.ssl.trustStore", // + "javax.net.ssl.trustStorePassword", // + "javax.net.ssl.trustStoreProvider", // + "javax.net.ssl.trustStoreType", // + "javax.net.ssl.keyStore", // + "javax.net.ssl.keyStorePassword", // + "javax.net.ssl.keyStoreProvider", // + "javax.net.ssl.keyStoreType"); + + @TempDir + private Path tempDir; + + private Map systemPropertyBackups = new HashMap<>(); + private SSLContext previousSslContext; + + @BeforeEach + public void setup() throws Exception { + for (String property : SYSTEM_PROPERTIES_TO_BACKUP_AND_RESTORE) { + systemPropertyBackups.put(property, System.getProperty(property, null)); + } + previousSslContext = SSLContext.getDefault(); + System.setProperty("eclipse.platform.mergeTrust", "true"); + } + + @AfterEach + public void teardown() { + systemPropertyBackups.forEach((property, backupValue) -> { + if (backupValue == null) { + System.clearProperty(property); + } else { + System.setProperty(property, backupValue); + } + }); + SSLContext.setDefault(previousSslContext); + } + + @Test + public void loadTrustManagers_Default() throws Exception { + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedTrustManagers, arrayWithSize(1)); + assertThat(keyStoreUtil.recordedTrustManagers[0], instanceOf(CollectionTrustManager.class)); + assertThat(((CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]).getAcceptedIssuers(), + not(emptyArray())); + + CollectionTrustManager tm = (CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]; + + // jvm + assertThat(tm.getTrustManagers(), not(empty())); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, not(empty())); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).manager(), is(tm.getTrustManagers().get(0))); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).store(), is(nullValue())); + assertThat( + Arrays.stream(tm.getTrustManagers().get(0).getAcceptedIssuers()) + .map(X509Certificate::getSubjectX500Principal).map(X500Principal::getName).toList(), + hasItem(matchesRegex("(?i).*digicert.*root.*"))); + + if (OS.WINDOWS.equals(OS.current())) { + assertThat(tm.getTrustManagers(), hasSize(2)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(2)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(1).manager(), + is(tm.getTrustManagers().get(1))); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(1).store().getType(), is("Windows-ROOT")); + assertThat( + Arrays.stream(tm.getTrustManagers().get(1).getAcceptedIssuers()) + .map(X509Certificate::getSubjectX500Principal).map(X500Principal::getName).toList(), + hasItem(matchesRegex("(?i).*digicert.*root.*"))); + } else if (OS.MAC.equals(OS.current())) { + assertThat(tm.getTrustManagers(), hasSize(2)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(2)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(1).manager(), + is(tm.getTrustManagers().get(1))); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(1).store().getType(), is("KeychainStore")); + // Apple KeychainStore only includes the 'System' certificates + // (enterprise/admin managed) + // but not the 'System Roots' ones (public CAs). + // There's nothing guaranteed / deterministic in the 'System' on CI machines + // that we could check for here... + } else { + assertThat(tm.getTrustManagers(), hasSize(1)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(1)); + } + + // no private keys + assertThat(keyStoreUtil.recordedKeyManagers, emptyArray()); + } + + @Test + public void loadTrustManagers_TrustSystemPropertiesPointToCustomTrustStore() throws Exception { + + System.setProperty("javax.net.ssl.trustStore", copyResourceToTempDirAndGetPath("truststore.jks")); + System.setProperty("javax.net.ssl.trustStorePassword", "verysecret"); + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedTrustManagers, arrayWithSize(1)); + assertThat(((CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]).getAcceptedIssuers(), + not(emptyArray())); + + CollectionTrustManager tm = (CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]; + + assertThat(tm.getTrustManagers(), hasSize(1)); // only the properties-based store + + assertThat( + Arrays.stream(tm.getTrustManagers().get(0).getAcceptedIssuers()) + .map(X509Certificate::getSubjectX500Principal).map(X500Principal::getName).toList(), + hasItem("CN=Test,C=DE")); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(1)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).manager(), is(tm.getTrustManagers().get(0))); + // null caused KeyManagerFactory to load default system properties + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).store(), is(nullValue())); + + assertThat(keyStoreUtil.recordedKeyManagers, emptyArray()); + } + + @Test + @EnabledOnOs({ OS.WINDOWS, OS.MAC }) + public void loadTrustManagers_TrustSystemPropertiesPointToPlatformSpecificKeystore() throws Exception { + if (OS.WINDOWS.equals(OS.current())) { + System.setProperty("javax.net.ssl.trustStore", "NONE"); + System.setProperty("javax.net.ssl.trustStoreType", "Windows-ROOT"); + } else if (OS.MAC.equals(OS.current())) { + System.setProperty("javax.net.ssl.trustStore", "NONE"); + System.setProperty("javax.net.ssl.trustStoreType", "KeychainStore"); + System.setProperty("javax.net.ssl.trustStoreProvider", "Apple"); + } + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedTrustManagers, arrayWithSize(1)); + + CollectionTrustManager tm = (CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]; + + assertThat(tm.getTrustManagers(), hasSize(1)); // only the properties-based store + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(1)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).manager(), is(tm.getTrustManagers().get(0))); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).store(), is(nullValue())); + + if (OS.WINDOWS.equals(OS.current())) { + assertThat(((CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]).getAcceptedIssuers(), + not(emptyArray())); + assertThat( + Arrays.stream(tm.getTrustManagers().get(0).getAcceptedIssuers()) + .map(X509Certificate::getSubjectX500Principal).map(X500Principal::getName).toList(), + hasItem(matchesRegex("(?i).*digicert.*root.*"))); + } else if (OS.MAC.equals(OS.current())) { + // Apple KeychainStore only includes the 'System' certificates + // (enterprise/admin managed) + // but not the 'System Roots' ones (public CAs). + // There's nothing guaranteed / deterministic in the 'System' on CI machines + // that we could check for here... + } + } + + @Test + public void loadKeyManagers_Default() throws Exception { + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedKeyManagers, emptyArray()); + assertThat(keyStoreUtil.createdKeyManagersAndKeyStores, hasSize(0)); + } + + @Test + public void loadKeyManagers_KeySystemPropertiesPointToCustomKeyStore() throws Exception { + + System.setProperty("javax.net.ssl.keyStore", copyResourceToTempDirAndGetPath("keystore.p12")); + System.setProperty("javax.net.ssl.keyStorePassword", "verysecret"); + System.setProperty("javax.net.ssl.keyStoreType", "PKCS12"); + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedKeyManagers, arrayWithSize(1)); + assertThat(keyStoreUtil.recordedKeyManagers[0], instanceOf(X509KeyManager.class)); + + X509KeyManager km = (X509KeyManager) keyStoreUtil.recordedKeyManagers[0]; + + assertThat(keyStoreUtil.createdKeyManagersAndKeyStores, hasSize(1)); + assertThat(keyStoreUtil.createdKeyManagersAndKeyStores.get(0).manager(), is(km)); + assertThat(keyStoreUtil.createdKeyManagersAndKeyStores.get(0).store().getType(), is("PKCS12")); + + assertThat(km.getPrivateKey("test.key"), not(nullValue())); + } + + @Test + public void optInSystemPropertyNotSet() throws Exception { + System.clearProperty("eclipse.platform.mergeTrust"); + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(previousSslContext)); + } + + private String copyResourceToTempDirAndGetPath(String resourceName) throws IOException { + Path file = tempDir.resolve(resourceName); + Files.copy(getClass().getResourceAsStream(resourceName), file, StandardCopyOption.REPLACE_EXISTING); + return file.toAbsolutePath().toString(); + } + + private static final class TestSpecificKeyStoreUtil extends KeyStoreUtil { + + public TestSpecificKeyStoreUtil() { + super(Platform.getOS()); + } + + public static record X509TrustManagerAndKeyStore(X509TrustManager manager, KeyStore store) { + } + + public static record X509KeyManagerAndKeyStore(X509KeyManager manager, KeyStore store) { + } + + public TrustManager[] recordedTrustManagers; + public KeyManager[] recordedKeyManagers; + public SSLContext recordedSslContext; + public final List createdTrustManagersAndKeyStores = new ArrayList<>(); + public final List createdKeyManagersAndKeyStores = new ArrayList<>(); + + @Override + protected X509TrustManager createX509TrustManager(KeyStore keyStore) throws GeneralSecurityException { + X509TrustManager manager = super.createX509TrustManager(keyStore); + this.createdTrustManagersAndKeyStores.add(new X509TrustManagerAndKeyStore(manager, keyStore)); + return manager; + } + + @Override + protected X509KeyManager createX509KeyManager(KeyStore keyStore, char[] password) + throws GeneralSecurityException { + X509KeyManager manager = super.createX509KeyManager(keyStore, password); + this.createdKeyManagersAndKeyStores.add(new X509KeyManagerAndKeyStore(manager, keyStore)); + return manager; + } + + @Override + protected void initSSLContext(SSLContext context, TrustManager[] trustManagers, KeyManager[] keyManagers, + SecureRandom random) throws KeyManagementException { + this.recordedTrustManagers = trustManagers; + this.recordedKeyManagers = keyManagers; + this.recordedSslContext = context; + super.initSSLContext(context, trustManagers, keyManagers, random); + } + } + +} diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/keystore.p12 b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..b86cf756e4e22be98b3a2ac35f5828fbd4e09d14 GIT binary patch literal 2472 zcmY*Zc{~#gAKzxyrirw8ay4g!%r#cZoVllx<$N5ul6!J(naMmDk1J=65=FVsWjV@` z`^Y`YRfr6aJDwh&&-=bTpZAa7^*w%neo++Ia}baXMSB+S)Ll;C31A)tW(uaj z43A+w6otL=|0wo+Foiw$7|uGbG|0*Sy5Jl@P#%RHdkm_hTz)y&IZ>7wSFL)+h*mQuIe;nPfl}xO+KF##FXc^^EAPc<9eN!>j)d7o(SF}A|9i>KFJGjO zSGQfuNL=7b@Y$l&g+S!E$n;ud%Xw=_){b0BSGB7CWyYzVM6s|!c1Dx+mK$U*PsVZB zBk3#qlpep)2k)XdNL0oP{~LNwEDCtjcO6qpS_3j|D+7mlVsUCTc|W;R=wYbq(M-zc zWnzE+!1|++TW_m7_??f^&uA#c(H+j14XP1ue{;n}rk_cNwdtto5oze;GGm zrp_qBcpJ}Uuzv~`KLFzu<+L8B+ovnx^M-mST4asiY^$N;C!CFT6R&@JdX>@HX4~xO z6ar45DyviwfK4;{npu14oSsT5T`*n^Wzb=J!b-8|c05a@3>~Ce5>`?4=Wh|bxD|Z+ z3Uk1^>@jPzkFDZP{cAht@-wHuXCKKlRO|ol){Wc+%a*8lmONFUD_{4o@op1mw4c$`x1U2dxJx3kQWp z#-+ZJG?_bUM&C8Jx%OzpiX&88bx4e)(KId83H~z?_h^m?g|ry(^(05>1{Pa1Qy=XT z<`3(+2OhJW{q5vBCL+1g-JC+A(h)^V5RFKjl;MOk&{&;&{*UGP^r!!we$dy#MS&JTHE!?3Q6i88&W4C9d4 z;_n<*7C)GyU+w&4B}`7VZm3Kyh{wHrG_^RoLJ6Veof(iZPH$k?E8+sc+!;33ljjXj zk_+%#Eygpu+tl@IS<#D}x`PRS42d_K*2wJo8eds>Yr3!3Xm$(62p za8N7~?tB@znk=#7ip0LwDp)gYrU~Cmi$OuLUcQXnFgiwd9_j+|E0^RoaAc;cb4YTL^^sf)n@dXy6z-_XEkRfRNgllanR9gOG2;;54aVh?lk?vn0KLZ_kx zJ4>!I$2NV)n{wb{Qq|xH@iYspscUoyh-Mr-)mas#zk$Abc)F;R6OoF^Y)z9!&wQ*E zNIpI0V9sxA7ZZ%Eq+dAMJ70RQ^JX(W>k4i~tjpa|o7zjpaHV8q!jbA1@pm*d0iYpW zTa8c6wC|b;h?z{@cNI+)T#CI~mUxsY8ZJ1F6TPQRmU#H7+UkBoikLd@-+dB_{5K!k z$|7vHoE+sALQ}L?c1!gRwx5qp7LKV1>Mdng6Jm)xLxAf^sx{Kjg${3djBDtG&nfah zyk$FJc?eIJ^Uk{37V`$sQ-P0FNZz^Golh7 z&Vn!}lZc{?*xA7xQ-__j%I@}rv~>}Acb<5eF|jcXdDtno36h z>!RG*T{`H>cF5yyMOfht{|{RC^#bbyBqxxKp9U=G_;CcOdOJL6gfnQkrMybO(lSHh z!NsSpletbFL*FYjO7p!jSL%%jp^!aYk5Emj%;mXvDj#x<7g)e)>J#*`1a^~nf_ARg zfww$Req!tEB@z8^`aYryRZmzEPktw%gIcq$z?Xn6q1@iVQ8IC6{X&9#2M8x6l^Kg+ zBaE;mfAPM7|ElvhT4DEX_N%snZ)?V^lAARMBZ*6LG4}Nlj!(y!AwMnhW)}@Q@b-9y zxR*G(ruSx;R&-u%r5{gfh@Nqnm2cArwkc(ypCrV6>sN|`WYEaTaiq)pLARH>Ifs1h z%(&gZW2H+7c5DPi&f2u;t_DN*+$NWUphXn@XPe^>WnII$lrRd%#!Lm5xA1a+Sm$=q z4b(N12nq&R1-;%5hd5%2RqbTGa^OTIr3!4gLoOk`JZolNo*>OQ}z2Pz0*vh z#`$K+mUG%}Z&UZ&4d^xdv$mo|`Qw%R_W=>j+GpPi=T9-;`*pTh`s>s7>t?myxOK9} zErn~Jfc!N(ZuOMwdXtWnEt0C?oMLk2$*1#$rC_VMQLi;F?JelJ z%6;ZeX;W*Pj`R21!r>lwmni(WB%#pI)2FDp=6AIG)oF*GpL$R#oS@~2GX+r-TIx<@9QUgWzsETGVr>FUaMeSRjwY=l@x%?D&+mz1{Tb$Q4n0|LmvOXZ+Y1xEVOmm*gJd!tB zeVdE>GQ$&Jj+C?RvD5DAT3wgZHBH(m*u=|ZyXybd$+~JsKke+Fe5>z{605cDB-M>q zFQ5Cn^Up;tY5xPhZvwJ}Ecztp@a~$h`sS;B_78oZ?e4yJ!AFcW{P3R>6Sps!V9$IT E09HyoX8-^I literal 0 HcmV?d00001 From 44145a3f43c55f2ffe0928d5f1eebcd43836812e Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Tue, 11 Nov 2025 15:38:28 +0100 Subject: [PATCH 54/56] Move copilot-instructions.md to AGENTS.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename .github/copilot-instructions.md to AGENTS.md at the root level to make it accessible to multiple AI coding assistants. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/copilot-instructions.md => AGENTS.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/copilot-instructions.md => AGENTS.md (100%) diff --git a/.github/copilot-instructions.md b/AGENTS.md similarity index 100% rename from .github/copilot-instructions.md rename to AGENTS.md From 0bab01912bd3e3ae88fd57401ed3dba352eb3ae0 Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Tue, 11 Nov 2025 15:39:26 +0100 Subject: [PATCH 55/56] Add CLAUDE.md with repository instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create CLAUDE.md file with repository-specific instructions for Claude AI coding assistant, copied from AGENTS.md content. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CLAUDE.md | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000000..20a6465a4e49 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,267 @@ +# Eclipse Platform Repository - Copilot Instructions + +## Repository Overview + +This repository contains the core Eclipse Platform components that form the basis for the Eclipse IDE. It is a **large-scale Java/OSGi project** (~120MB, 5,600+ Java files across 38 Maven modules) using **Maven/Tycho** for building Eclipse RCP bundles and features. + +**Key Technologies:** +- Language: Java (JDK 17+, targets JDK 21 in CI) +- Build: Maven 3.9+ with Eclipse Tycho (OSGi/RCP build tooling) +- Architecture: OSGi bundles organized as Eclipse plugins +- Testing: JUnit with Tycho Surefire plugin + +**Main Modules:** +- `runtime/` - Core runtime, jobs, expressions, content types (org.eclipse.core.runtime, org.eclipse.core.jobs) +- `resources/` - Workspace, filesystem, project management (org.eclipse.core.resources, org.eclipse.core.filesystem) +- `debug/` - Debug framework and UI, external tools, launch configurations +- `team/` - Version control framework (CVS examples) +- `ua/` - User assistance: help system, cheatsheets, tips +- `ant/` - Ant integration and UI +- `terminal/` - Terminal view +- `platform/` - SDK packaging + +## Critical Build Information + +**⚠️ IMPORTANT: This repository CANNOT be built in isolation.** It depends on a parent POM (`eclipse-platform-parent`) from the [eclipse.platform.releng.aggregator](https://github.com/eclipse-platform/eclipse.platform.releng.aggregator) repository. + +### Individual Bundle Builds + +Individual bundles CAN be built using the pre-configured profile if you have network access to Eclipse repositories: + +```bash +cd # e.g., runtime/bundles/org.eclipse.core.runtime +mvn clean verify -Pbuild-individual-bundles +``` + +The `-Pbuild-individual-bundles` profile (configured in `.mvn/maven.config`) enables the bundle to fetch the parent POM from https://repo.eclipse.org/content/repositories/eclipse/. + +**Note:** If network access to Eclipse repositories is blocked, individual bundle builds will fail. In such environments, code exploration and analysis can still be performed, but build verification is not possible. + +### Full Platform Build + +For full platform builds, use the aggregator repository which includes this repo as a Git submodule. The CI workflows in this repository delegate to workflows in the aggregator repository. + +### Build Profiles Used in CI + +The Jenkinsfile shows the complete build command: +```bash +mvn clean verify --batch-mode --fail-at-end \ + -Pbree-libs -Papi-check -Pjavadoc \ + -Dmaven.test.failure.ignore=true \ + -Dcompare-version-with-baselines.skip=false \ + -Dmaven.compiler.failOnWarning=false +``` + +Key profiles: +- `-Pbree-libs` - Bundle Runtime Execution Environment libraries +- `-Papi-check` - API baseline comparison (detects breaking changes) +- `-Pjavadoc` - Generate Javadoc + +## Testing + +**Test Organization:** +- Tests are in `/tests/` subdirectories (e.g., `runtime/tests/`, `resources/tests/`) +- Test bundles follow naming: `org.eclipse..tests.` +- Tests use JUnit 4/5 with Tycho Surefire + +**Running Tests:** +```bash +# Run tests for a specific bundle +cd +mvn clean verify -Pbuild-individual-bundles + +# Tests are automatically run during 'mvn verify' +# Test results: target/surefire-reports/TEST-*.xml +``` + +**Important Test Notes:** +- Some tests require graphical display (use Xvnc in CI - see Jenkinsfile) +- Tests in `debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/LocalSuite.java` require user terminal and should NOT run on build machines +- Test failures are allowed in CI (`-Dmaven.test.failure.ignore=true`) + +## Validation & CI Checks + +### GitHub Actions Workflows + +All workflows delegate to the aggregator repository: + +1. **PR Checks** (`.github/workflows/pr-checks.yml`): + - Freeze period verification + - No merge commits check + - Version increment verification (uses PDE API Tools) + +2. **Continuous Integration** (`.github/workflows/ci.yml`): + - Delegates to `mavenBuild.yml` in aggregator + - Runs full build with all profiles + +3. **CodeQL** (`.github/workflows/codeql.yml`): + - Security scanning for Java code + +### Local Validation Steps + +Before committing, verify your changes: + +```bash +# 1. Build the affected bundle +cd +mvn clean verify -Pbuild-individual-bundles + +# 2. Check for API issues (PDE API Tools) +# API baseline checks run automatically with -Papi-check +# Results in: target/apianalysis/*.xml + +# 3. Check for compiler warnings +# Results in: target/compilelogs/*.xml +``` + +### API Tools & Version Management + +**Critical:** Eclipse uses semantic versioning with API tooling enforcement: +- Major version: Breaking API changes +- Minor version: Binary compatible API additions, significant changes +- Service version: Bug fixes (increments: +1 for maintenance, +100 for next release) +- Qualifier: Build timestamp + +**Version Change Rules:** +1. API breaking change → Increment major version, reset minor/service to 0 +2. API addition (binary compatible) → Increment minor version, reset service to 0 +3. Bug fix in maintenance → Increment service by 1 +4. Bug fix in next release → Increment service by 100 + +**PDE API Tools automatically detects API changes and enforces version increments.** + +See `docs/VersionNumbering.md` and `docs/Evolving-Java-based-APIs.md` for complete details. + +## Project Structure + +### Root Files +- `pom.xml` - Main reactor POM (defines modules) +- `Jenkinsfile` - Jenkins CI pipeline configuration +- `.mvn/maven.config` - Default Maven options (includes `-Pbuild-individual-bundles`) +- `.gitignore` - Excludes `target/`, `bin/`, `*.class`, etc. + +### Key Configuration Files + +**Per Bundle:** +- `pom.xml` - Maven coordinates and build config +- `META-INF/MANIFEST.MF` - OSGi bundle manifest (Bundle-SymbolicName, Bundle-Version, dependencies) +- `build.properties` - Tycho/PDE build configuration (source folders, bin.includes) +- `.project` - Eclipse project descriptor +- `.classpath` - Eclipse classpath (typically generated) + +**Coding Standards:** +- `docs/Coding_Conventions.md` - Java coding style (follows Oracle conventions with modifications) +- `docs/Naming_Conventions.md` - Package/class naming rules +- Indent with tabs (4 spaces wide) +- Encoding: UTF-8 (see `.settings/org.eclipse.core.resources.prefs`) + +## Common Pitfalls & Solutions + +### 1. Parent POM Resolution Failure +**Error:** `Non-resolvable parent POM for org.eclipse.platform:eclipse.platform` + +**Solution:** Always use `-Pbuild-individual-bundles` profile when building individual bundles. This profile is pre-configured in `.mvn/maven.config` but may be needed explicitly in some contexts. + +### 2. Missing Dependencies During Build +**Error:** Cannot resolve bundle dependencies + +**Solution:** +- Individual bundles fetch dependencies from Eclipse repositories +- Ensure https://repo.eclipse.org is accessible +- Clean local Maven cache if corrupted: `rm -rf ~/.m2/repository/org/eclipse` + +### 3. Test Failures Requiring Display +**Error:** Tests fail with "No display available" + +**Solution:** +- Tests requiring GUI run automatically on CI (Xvnc configured in Jenkinsfile) +- For local testing, use Xvfb: `xvfb-run mvn verify` +- Or skip tests: `mvn verify -DskipTests` + +### 4. API Tools Errors +**Error:** "API baseline errors found" + +**Solution:** +- Review changes in `target/apianalysis/*.xml` +- If API changed, update bundle version in `META-INF/MANIFEST.MF` +- Follow version increment rules (see docs/VersionNumbering.md) +- For intentional API breaks, update baseline comparison + +### 5. Build Timeouts +Maven operations can take considerable time: +- Clean build of single bundle: 1-3 minutes +- Full platform build (aggregator): 30-60 minutes +- Test execution: Variable, some test suites take 10+ minutes + +**Set adequate timeouts when building (default 120s may not be enough):** +```bash +mvn verify -Pbuild-individual-bundles # May need 180-300 seconds +``` + +## Making Changes + +### Typical Change Workflow + +1. **Locate the Bundle:** + - Runtime/core services → `runtime/bundles/` + - Resource/workspace → `resources/bundles/` + - Debug/launch → `debug/` + - Help/documentation → `ua/` + +2. **Make Code Changes:** + - Edit Java sources in bundle's `src/` directory + - Follow coding conventions (see `docs/Coding_Conventions.md`) + - Add/update Javadoc for public APIs + +3. **Update MANIFEST.MF if needed:** + - Changed API? Update `Bundle-Version` following semantic versioning + - New dependencies? Add to `Require-Bundle` or `Import-Package` + +4. **Build and Test:** + ```bash + cd + mvn clean verify -Pbuild-individual-bundles + ``` + +5. **Verify No API Issues:** + - Check `target/apianalysis/*.xml` for API baseline errors + - Address any version increment requirements + +6. **Commit:** + - Write clear commit message + - Reference issue number if applicable + +## File Locations Reference + +**Documentation:** All in `docs/` +- `docs/Coding_Conventions.md` - Code style +- `docs/API_Central.md` - API guidelines hub +- `docs/VersionNumbering.md` - Version management +- `docs/FAQ/` - 200+ FAQ markdown files + +**Build Configuration:** +- `.mvn/maven.config` - Maven CLI defaults +- `Jenkinsfile` - CI build definition (60 min timeout) +- `.github/workflows/*.yml` - GitHub Actions (all delegate to aggregator) + +**Key Bundle Directories:** +- `runtime/bundles/org.eclipse.core.runtime` - Core Platform Runtime +- `runtime/bundles/org.eclipse.core.jobs` - Jobs and scheduling +- `resources/bundles/org.eclipse.core.resources` - Workspace API +- `resources/bundles/org.eclipse.core.filesystem` - Filesystem abstraction + +## Working Efficiently + +**Trust these instructions first.** This repository has a complex build setup that cannot be fully explored from the repository alone. The information above captures the essential knowledge needed to: +- Understand build requirements and limitations +- Make targeted changes without breaking CI +- Navigate the codebase effectively +- Avoid common build pitfalls + +Only search beyond these instructions if: +- Specific API behavior needs clarification (check `docs/FAQ/`) +- Detailed versioning rules are needed (check `docs/VersionNumbering.md`) +- You need examples of existing code patterns (search Java sources) +- CI is failing with an error not covered here (check Jenkinsfile and workflow YAMLs) + +**When in doubt:** Build at the bundle level with `-Pbuild-individual-bundles` profile and verify tests pass locally before pushing changes. From f05e114164cb63505852c60d666d24a55c7eb2dc Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Tue, 11 Nov 2025 15:39:59 +0100 Subject: [PATCH 56/56] Update AGENTS.md to support multiple AI assistants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update AGENTS.md title and add AI agent-specific sections for GitHub Copilot, Claude Code, and other AI assistants. Provides guidance on the strengths of each tool and how they should interact with the repository. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- AGENTS.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 6ecc70a3eb24..f152e6cacf6d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,4 +1,6 @@ -# Eclipse Platform Repository - Copilot Instructions +# Eclipse Platform Repository - AI Agent Instructions + +This file provides guidance for AI coding assistants (GitHub Copilot, Claude Code, etc.) working with this repository. ## Repository Overview @@ -250,3 +252,22 @@ Only search beyond these instructions if: - CI is failing with an error not covered here (check Jenkinsfile and workflow YAMLs) **When in doubt:** Build at the bundle level with `-Pbuild-individual-bundles` profile and verify tests pass locally before pushing changes. + +## AI Agent-Specific Notes + +### For GitHub Copilot +- This file is automatically read by GitHub Copilot when providing code suggestions +- Copilot uses this context to understand the project structure and conventions +- Copilot excels at inline code completion and small-scale refactoring + +### For Claude Code +- Claude Code has access to this file via the `CLAUDE.md` file in the repository root +- Claude Code is better suited for multi-file refactoring and architectural changes +- Use Claude Code for tasks requiring deep codebase understanding across multiple modules +- Claude Code can execute builds and tests directly via Maven commands + +### For Other AI Agents +- Read this file to understand the repository structure and build requirements +- Follow the coding conventions in `docs/Coding_Conventions.md` +- Always test changes with `mvn clean verify -Pbuild-individual-bundles` before committing +- Check API baseline with `-Papi-check` when modifying public APIs