A collection of experimental Eclipse JDT (Java Development Tools) cleanup plugins and tools. This repository demonstrates how to build custom JDT cleanups, quick fixes, and related tooling for Eclipse-based Java development.
Main Technologies: Eclipse JDT, Java 21, Maven/Tycho 5.0.1
Status: Work in Progress β All plugins are experimental and intended for testing purposes.
This project provides:
- Custom JDT Cleanup Plugins: Automated code transformations for encoding, JUnit migration, functional programming patterns, and more
- Eclipse Product Build: A complete Eclipse product with bundled features
- P2 Update Site: Installable plugins via Eclipse update mechanism
- Test Infrastructure: JUnit 5-based tests for all cleanup implementations
- GitHub Actions Integration: Automated code cleanup for pull requests (See GITHUB_ACTIONS.md)
All plugins are work-in-progress and intended for experimentation and learning.
Add one of the following update sites to your Eclipse installation:
https://carstenartur.github.io/sandbox/releases/
Use this for stable, tested versions suitable for production use.
https://carstenartur.github.io/sandbox/snapshots/latest/
Use this to test the latest features. Updated automatically on every commit to main. May be unstable.
- Open Eclipse IDE
- Go to Help β Install New Software...
- Click Add... button
- Enter:
- Name:
Sandbox(or any name you prefer) - Location: One of the update site URLs above
- Name:
- Select the features you want to install from the available list
- Click Next and follow the installation wizard
- Restart Eclipse when prompted
β οΈ Warning: These plugins are experimental. Test them in a development environment before using in production.
The Sandbox plugins are also available on the Eclipse Marketplace.
The Sandbox project uses an automated release workflow:
- Navigate to Actions β Release Workflow β Run workflow
- Enter the release version (e.g.,
1.2.2) - Enter the next SNAPSHOT version (e.g.,
1.2.3-SNAPSHOT) - Click Run workflow
The workflow automatically:
- Updates all version files using
tycho-versions-plugin(exceptsandbox-functional-converter-core) - Builds and verifies the release
- Creates git tag and maintenance branch
- Deploys to GitHub Pages
- Generates release notes from closed issues
- Creates GitHub release
- Bumps to next SNAPSHOT version
The new release will be available at https://carstenartur.github.io/sandbox/releases/X.Y.Z/ within a few minutes.
- Overview
- π Installation
- π¦ Release Process
- GitHub Actions Integration
- Build Instructions
- Eclipse Version Configuration
- Quickstart
- CI Status
- What's Included
- Projects
- 1.
sandbox_cleanup_application - 2.
sandbox_encoding_quickfix - 3.
sandbox_extra_search - 4.
sandbox_usage_view - 5.
sandbox_platform_helper - 6.
sandbox_tools - 7.
sandbox_jface_cleanup - 8.
sandbox_functional_converter- Functional Converter Cleanup β Transform Imperative Loops into Functional Java 8 Streams
- Source and Test Basis
- Supported Transformations
- Examples
- Reductions (Accumulators)
- Not Yet Supported (Disabled Tests)
- Ignored Cases β No Cleanup Triggered
- Java Version Compatibility
- Cleanup Name & Activation
- Limitations
- Summary
- 9.
sandbox_junit - 10.
sandbox_method_reuse - 11.
sandbox_xml_cleanup
- 1.
- Installation
- Documentation
- Contributing
- Release Process
- License
This repository includes a Docker-based GitHub Action for automated code cleanup on pull requests. The action uses the sandbox cleanup application to apply Eclipse JDT cleanups directly in your GitHub workflows.
- Automatic PR Cleanup: Already configured! Opens/updates to PRs with Java files trigger cleanup automatically
- Manual Cleanup: Go to Actions β Manual Cleanup β Run workflow
- Custom Integration: Use
./.github/actions/cleanup-actionin your workflows
β
Automated cleanup on pull requests
β
Configurable profiles (minimal/standard/aggressive)
β
All sandbox + Eclipse JDT cleanups included
β
Auto-commit changes to PR branch
β
Manual trigger with customizable options
π Full Documentation | Workflows Guide | Action Details
IMPORTANT: This project (main branch, targeting Eclipse 2025-09) requires Java 21 or later.
The project uses Tycho 5.0.1 which requires Java 21. Building with Java 17 or earlier will fail with:
UnsupportedClassVersionError: ... has been compiled by a more recent version of the Java Runtime (class file version 65.0)
Verify your Java version:
java -version # Should show Java 21 or laterThe project supports Maven profiles to optimize build speed:
| Profile | Modules Built | Use Case |
|---|---|---|
dev (default) |
All bundles, features, tests | Fast local development |
product |
+ Eclipse Product (sandbox_product) |
Building distributable product |
repo |
+ P2 Update Site (sandbox_updatesite) |
Building update site |
jacoco |
+ Coverage reports | CI/Coverage builds |
reports |
+ HTML test reports | CI/Test report builds |
| Command | Description |
|---|---|
mvn -T 1C verify |
Quick dev build (fastest) |
mvn -Pproduct -T 1C verify |
Build with Eclipse product |
mvn -Prepo -T 1C verify |
Build with P2 update site |
mvn -Pproduct,repo -T 1C verify |
Full release build |
mvn -Pjacoco,product,repo -T 1C verify |
Full CI build with coverage |
mvn -T 1C -DskipTests verify |
Skip tests for local iteration |
The project supports different build profiles for different purposes. Choose the appropriate command based on your needs:
For rapid iteration during development, use the default build which excludes heavy product materialization and p2 repository assembly:
mvn -T 1C verify- Builds: All bundles, features, and tests
- Skips: Product materialization (
sandbox_product) and p2 repository assembly (sandbox_updatesite) - Use case: Fast feedback during development, testing code changes
- Time: Significantly faster than full build
You can skip tests for even faster iteration:
mvn -T 1C -DskipTests verifyTo build the Eclipse product with p2-director materialization (creates installable Eclipse distributions):
mvn -Pproduct -T 1C verify- Builds: Everything in default build + Eclipse product
- Output:
sandbox_product/target/products/ - Use case: Testing the Eclipse product locally
To build the p2 update site repository (for plugin distribution):
mvn -Prepo -T 1C verify- Builds: Everything in default build + p2 update site
- Output:
sandbox_updatesite/target/repository/ - Use case: Creating update site for plugin distribution
For complete builds including product, repository, and code coverage:
mvn -Pproduct,repo,jacoco -T 1C verify- Builds: Everything (bundles, features, tests, product, repository, coverage)
- Output: Complete release artifacts in respective module
target/directories - Coverage Report:
sandbox_coverage/target/site/jacoco-aggregate/ - Use case: Release builds, CI main branch builds
To build a WAR file that contains the update site:
mvn -Dinclude=web -Pproduct,jacoco -T 1C verify- The WAR file will be located in
sandbox_web/target
A Makefile is provided for easier build commands:
make dev # Fast development build (skips tests)
make product # Build with product (requires xvfb for tests)
make repo # Build with repository (requires xvfb for tests)
make release # Full release build with coverage (requires xvfb for tests)
make test # Run tests with coverage (requires xvfb)
make clean # Clean all build artifacts
make help # Show all available targets-T 1C: Enables parallel builds with 1 thread per CPU core (faster builds)-DskipTests: Skips test execution (faster iteration)-Pjacoco: Enables JaCoCo code coverage-Pproduct: Includes Eclipse product build-Prepo: Includes p2 repository build
- Default (no profiles): Fast development build - bundles, features, and tests only
product: Adds Eclipse product materialization (heavy step, takes time)repo: Adds p2 update site repository assembly (heavy step, takes time)jacoco: Adds code coverage reporting (includessandbox_coveragemodule)reports: Adds HTML test report generation (use without-T 1Cto avoid thread-safety warning)web: Adds WAR file with update site (requires-Dinclude=webproperty, also buildssandbox_product)
Backward Compatibility: The command mvn -Pproduct,repo verify produces the same result as the previous full build behavior.
This error occurs when building with Java 17 or earlier:
TypeNotPresentException: Type P2ArtifactRepositoryLayout not present
...class file version 65.0, this version only recognizes class file versions up to 61.0
Solution: Upgrade to Java 21 or later. Verify with java -version.
This usually indicates a Java version mismatch. Check that:
JAVA_HOMEis set to Java 21+java -versionshows Java 21+- Maven is using the correct Java version:
mvn -version
The Eclipse version (SimRel release) used by this project is not centrally configured. When updating to a new Eclipse release, you must update the version reference in multiple files throughout the repository.
When migrating to a new Eclipse version, update the following files:
-
pom.xml(root)- Repository URLs in the
<repositories>section - Example:
https://download.eclipse.org/releases/2025-09/ - Also update Orbit repository URL:
https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/2025-09/
- Repository URLs in the
-
sandbox_target/eclipse.target- Primary Eclipse release repository URL in first
<location>block - Example:
<repository location="https://download.eclipse.org/releases/2025-09/"/> - Also update Orbit repository URL
- Primary Eclipse release repository URL in first
-
sandbox_product/category.xml- Repository reference location
- Example:
<repository-reference location="https://download.eclipse.org/releases/2025-09/" .../>
-
sandbox_product/sandbox.product- Repository locations in
<repositories>section - Example:
<repository location="https://download.eclipse.org/releases/2025-09/" .../>
- Repository locations in
-
sandbox_oomph/sandbox.setup- P2 repository URL in the version-specific
<setupTask>block - Example:
<repository url="https://download.eclipse.org/releases/2025-09"/>
- P2 repository URL in the version-specific
- Use HTTPS: All Eclipse download URLs should use
https://(nothttp://) - Use explicit versions: Prefer explicit version URLs (e.g.,
2025-09) overlatestfor reproducible builds - Keep versions aligned: All files should reference the same Eclipse SimRel version
- Git URLs: Use HTTPS for git clone URLs (e.g.,
https://github.com/..., notgit://) - Main branch: All Oomph setup files should reference the
mainbranch, notmaster
- Eclipse Version: 2025-09
- Java Version: 21
- Tycho Version: 5.0.1
- Default Branch:
main
After building the project, you can run the Eclipse product with the bundled cleanup plugins:
# Navigate to the product directory
cd sandbox_product/target/products/org.sandbox.product/
# Launch Eclipse
./eclipseYou can apply cleanup transformations using the Eclipse JDT formatter application pattern:
eclipse -nosplash -consolelog -debug \
-application org.eclipse.jdt.core.JavaCodeFormatter \
-verbose -config MyCleanupSettings.ini MyClassToCleanup.javaNote: Replace
MyCleanupSettings.iniwith your cleanup configuration file andMyClassToCleanup.javawith the Java file you want to process.
You can install the cleanup plugins into your existing Eclipse installation using the P2 update site.
See the Installation section above for detailed instructions and update site URLs.
The update sites provide:
- Stable Releases:
https://carstenartur.github.io/sandbox/releases/- Tested, stable versions - Latest Snapshots:
https://carstenartur.github.io/sandbox/snapshots/latest/- Latest development builds
β οΈ Warning: These plugins are experimental. Test them in a development environment before using in production.
Code Coverage Reports: Available at https://carstenartur.github.io/sandbox/coverage/ (updated daily via scheduled build when there are commits to main, or on manual trigger)
Test Results: Available at https://carstenartur.github.io/sandbox/tests/ (updated on every push to main)
The JaCoCo coverage reports show code coverage statistics for the entire codebase:
- Location:
https://carstenartur.github.io/sandbox/coverage/ - Content: Line, branch, and method coverage for all modules
- Update Frequency: Daily via scheduled build (only when there are commits in the last 24 hours) or manual trigger
- Build Profile: Generated with full release build using
-Pjacoco,product,repoprofiles - Local Generation: Run
mvn -Pjacoco verifyto generate locally insandbox_coverage/target/site/jacoco-aggregate/ - Note: Coverage reports are NOT generated on normal push/PR builds to keep CI fast. They require the scheduled or manual coverage workflow.
HTML test reports for all test modules, showing detailed test execution results:
- Location:
https://carstenartur.github.io/sandbox/tests/ - Content:
- Individual test module reports (e.g.,
sandbox_encoding_quickfix_test,sandbox_functional_converter_test) - Test success/failure statistics
- Disabled tests (JUnit 5
@Disabledannotations) - Detailed test execution information
- Individual test module reports (e.g.,
- Update Frequency:
- Primary: Updated on every push to main branch (via normal CI build)
- Secondary: Also updated during scheduled coverage builds (includes full release build with all profiles)
- Build Profile:
- Normal builds (push/PR): No special profiles, fast build for quick feedback
- Scheduled builds: Uses
-Pjacoco,product,repoprofiles (full release build)
- Local Generation: Run the full reactor build (
mvn verify), and test reports will be automatically generated in each test module'starget/site/surefire-report.htmldirectory - Structure:
- Main index: Lists all test modules with links to their individual reports
- Module reports: Detailed test results for each module
The project uses two distinct CI workflows for efficient publishing:
Triggers: On push/PR to main branch
Purpose: Fast feedback and test result publishing
Build Command: mvn verify (no jacoco, product, or repo profiles)
What it does:
- Runs standard Maven/Tycho build
- Executes all tests
- Generates Surefire/JUnit HTML reports automatically (via maven-surefire-report-plugin)
- Collects test reports from all test modules
- Deploys test reports to GitHub Pages at
/tests
What it does NOT do:
- Does NOT generate code coverage (jacoco profile not active)
- Does NOT build Eclipse product or P2 repository (kept lean for speed)
Update guarantee: Test results are always current with the latest main branch commit
Triggers:
- Daily at midnight UTC (only if there were commits in the last 24 hours)
- Manual workflow dispatch
Purpose: Full release build with comprehensive coverage metrics
Build Command: mvn -Pjacoco,product,repo verify
What it does:
- Runs full release build with all profiles
- Generates JaCoCo code coverage reports
- Builds Eclipse product and P2 repository
- Deploys coverage reports to GitHub Pages at
/coverage - Deploys test reports to GitHub Pages at
/tests(as backup)
Update guarantee: Coverage reports are updated daily when there are new commits, but may be up to 24 hours behind the latest commit
Performance: Normal builds complete faster without heavy jacoco/product/repo profiles, providing quick feedback on PRs and commits
Separation of Concerns:
- Test results = Always current (every commit)
- Coverage metrics = Updated daily (comprehensive but not blocking fast feedback)
Resource Efficiency: Full release builds with coverage are expensive; running them daily (instead of on every commit) reduces CI resource usage while still maintaining up-to-date coverage metrics
| Branch | Java Version | Tycho Version |
|---|---|---|
main (2025-09) |
Java 21 | 5.0.1 |
2024-06+ |
Java 21 | 5.0.x |
2022-12+ |
Java 17 | 4.x |
Up to 2022-06 |
Java 11 | 3.x |
Note: Tycho 5.x requires Java 21+ at build time. Attempting to build with Java 17 will result in UnsupportedClassVersionError.
- Building for different Eclipse versions via GitHub Actions
- Creating custom JDT cleanups
- Setting up the SpotBugs Maven plugin to fail the build on issues
- Writing JUnit 5-based tests for JDT cleanups
- Configuring JaCoCo for test coverage
- Building an Eclipse product including new features
- Automatically building a WAR file including a P2 update site
All projects are considered work in progress unless otherwise noted.
Placeholder for a CLI-based cleanup application, similar to the Java code formatting tool:
eclipse -nosplash -consolelog -debug -application org.eclipse.jdt.core.JavaCodeFormatter -verbose -config MyCodingStandards.ini MyClassToBeFormatted.javaSee: https://bugs.eclipse.org/bugs/show_bug.cgi?id=75333
Replaces platform-dependent or implicit encoding usage with explicit, safe alternatives using StandardCharsets.UTF_8 or equivalent constants. Improves code portability and prevents encoding-related bugs across different platforms.
Key Features:
- Three cleanup strategies: Prefer UTF-8, Keep Behavior, or Aggregate UTF-8
- Java version-aware transformations (Java 7-21+)
- Supports FileReader, FileWriter, Files methods, Scanner, PrintWriter, and more
- Automatically adds imports and removes unnecessary exceptions
Quick Example:
// Before
Reader r = new FileReader(file);
List<String> lines = Files.readAllLines(path);
// After
Reader r = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);π Full Documentation: Plugin README | Architecture | TODO
Experimental search tool for identifying critical classes when upgrading Eclipse or Java versions.
Provides a table view of code objects, sorted by name, to detect inconsistent naming that could confuse developers.
Simplifies Eclipse Platform Status object creation by replacing verbose new Status(...) constructor calls with cleaner factory methods (Java 11+ / Eclipse 4.20+) or StatusHelper pattern (Java 8).
Key Features:
- Java version-aware transformations
- Reduces boilerplate in Status object creation
- Automatic selection between StatusHelper or factory methods
- Cleaner, more readable code
Quick Example:
// Before
IStatus status = new Status(IStatus.ERROR, "plugin.id", "Error message", exception);
// After (Java 11+ / Eclipse 4.20+)
IStatus status = Status.error("Error message", exception);π Full Documentation: Plugin README | Architecture | TODO
While-to-For loop converter β already merged into Eclipse JDT.
Automates migration from deprecated SubProgressMonitor to modern SubMonitor API. The cleanup is idempotent and handles variable name collisions.
Key Features:
- Transforms
beginTask()+SubProgressMonitortoSubMonitor.convert()+split() - Handles style flags and multiple monitor instances
- Idempotent - safe to run multiple times
- Automatic variable name conflict resolution
Quick Example:
// Before
monitor.beginTask("Task", 100);
IProgressMonitor sub = new SubProgressMonitor(monitor, 60);
// After
SubMonitor subMonitor = SubMonitor.convert(monitor, "Task", 100);
IProgressMonitor sub = subMonitor.split(60);π Full Documentation: Plugin README | Architecture | TODO
This cleanup modernizes imperative Java loop constructs by transforming them into functional-style equivalents using Java 8 Streams, map, filter, reduce, and forEach.
π Architecture Documentation: See ARCHITECTURE.md for detailed implementation details, design patterns, and internal components.
This cleanup is fully tested in:
sandbox_functional_converter_test/src/org/sandbox/jdt/ui/tests/quickfix/Java8CleanUpTest.java
The test class defines:
- 25 enabled test cases covering fully supported loop transformation patterns
- A list of
@Disabledscenarios representing future features and unsupported patterns - A set of
@ValueSourcecases where no transformation should be applied (edge cases)
The cleanup currently supports the following patterns:
| Pattern | Transformed To |
|---|---|
| Simple enhanced for-loops | list.forEach(...) or list.stream().forEach(...) |
| Mapping inside loops | .stream().map(...) |
Filtering via if or continue |
.stream().filter(...) |
| Null safety checks | .filter(l -> l != null).map(...) |
| Reductions (sum/counter) | .stream().map(...).reduce(...) |
| MAX/MIN reductions | .reduce(init, Math::max) or .reduce(init, Math::min) |
String concatenation in loops |
.reduce(..., String::concat) |
Conditional early return true |
.anyMatch(...) |
Conditional early return false |
.noneMatch(...) |
| Conditional check all valid | .allMatch(...) |
| Method calls inside mapping/filtering | map(x -> method(x)), filter(...) |
Combined filter, map, forEach |
Chained stream transformations |
| Nested conditionals | Multiple .filter(...) operations |
| Increment/decrement reducers | .map(_item -> 1).reduce(0, Integer::sum) |
| Compound assignment reducers | .map(expr).reduce(init, operator) |
Enabled Test Cases (25 total):
SIMPLECONVERT,CHAININGMAP,ChainingFilterMapForEachConvertSmoothLongerChaining,MergingOperations,BeautificationWorks,BeautificationWorks2NonFilteringIfChaining,ContinuingIfFilterSingleStatementSimpleReducer,ChainedReducer,IncrementReducer,AccumulatingMapReduceDOUBLEINCREMENTREDUCER,DecrementingReducer,ChainedReducerWithMerging,StringConcatChainedAnyMatch,ChainedNoneMatchNoNeededVariablesMerging,SomeChainingWithNoNeededVarMaxReducer,MinReducer,MaxWithExpression,MinWithExpressionFilteredMaxReduction,ChainedMapWithMinReduction,ComplexFilterMapMaxReductionContinueWithMapAndForEachSimpleAllMatch,AllMatchWithNullCheck,ChainedAllMatchNestedFilterCombination
Before:
for (Integer l : list) {
System.out.println(l);
}After:
list.forEach(l -> System.out.println(l));Before:
for (Integer l : list) {
if (l != null) {
String s = l.toString();
System.out.println(s);
}
}After:
list.stream()
.filter(l -> (l != null))
.map(l -> l.toString())
.forEachOrdered(s -> {
System.out.println(s);
});Before:
for (Integer l : list) {
if (l == null) {
continue;
}
String s = l.toString();
System.out.println(s);
}After:
list.stream()
.filter(l -> !(l == null))
.map(l -> l.toString())
.forEachOrdered(s -> {
System.out.println(s);
});Before:
for (Integer l : list) {
String s = l.toString();
Object o = foo(s);
if (o == null)
return true;
}
return false;After:
if (list.stream()
.map(l -> l.toString())
.map(s -> foo(s))
.anyMatch(o -> (o == null))) {
return true;
}
return false;Before:
for (String item : items) {
if (!item.startsWith("valid")) {
return false;
}
}
return true;After:
if (!items.stream().allMatch(item -> item.startsWith("valid"))) {
return false;
}
return true;Before:
int max = Integer.MIN_VALUE;
for (Integer num : numbers) {
max = Math.max(max, num);
}After:
int max = Integer.MIN_VALUE;
max = numbers.stream().reduce(max, Math::max);Similarly for Math.min() β .reduce(min, Math::min)
Before:
int maxLen = 0;
for (String str : strings) {
maxLen = Math.max(maxLen, str.length());
}After:
int maxLen = 0;
maxLen = strings.stream()
.map(str -> str.length())
.reduce(maxLen, Math::max);Before:
for (String item : items) {
if (item != null) {
if (item.length() > 5) {
System.out.println(item);
}
}
}After:
items.stream()
.filter(item -> (item != null))
.filter(item -> (item.length() > 5))
.forEachOrdered(item -> {
System.out.println(item);
});Before:
int count = 0;
for (String s : list) {
count += 1;
}After:
int count = list.stream()
.map(_item -> 1)
.reduce(0, Integer::sum);Before:
int sum = 0;
for (Integer l : list) {
sum += foo(l);
}After:
int sum = list.stream()
.map(l -> foo(l))
.reduce(0, Integer::sum);Also supported:
- Decrementing:
i -= 1β.reduce(i, (a, b) -> a - b) - Type-aware literals:
1for int,1Lfor long,1.0for double,1.0ffor float - String concatenation:
.reduce("", String::concat)
The following patterns are currently not supported and are marked @Disabled in the test suite:
| Pattern Description | Reason / Required Feature |
|---|---|
Map.put(...) inside loop |
Needs Collectors.toMap(...) support |
Early break inside loop body |
Requires stream short-circuit modeling (findFirst()) |
Labeled continue or break (label:) |
Not expressible via Stream API |
Complex if-else-return branches |
Requires flow graph and branching preservation |
throw inside loop |
Non-convertible β not compatible with Stream flow |
| Multiple accumulators in one loop | State mutation not easily transferable |
These patterns are intentionally excluded from transformation to maintain semantic correctness and safety.
The cleanup does not modify code in the following edge cases (validated by @ValueSource tests):
- Non-loop constructs
- Loops over arrays instead of
ListorIterable - Loops with early
return,throw, or labeledcontinue - Loops mixing multiple mutable accumulators
- Loops with side effects that cannot be safely preserved
| API Used | Requires Java |
|---|---|
Stream, map, filter |
Java 8+ |
forEach, forEachOrdered |
Java 8+ |
anyMatch, noneMatch |
Java 8+ |
reduce |
Java 8+ |
Collectors.toList() |
Java 8+ |
This cleanup is designed for Java 8+ projects and uses only APIs available since Java 8.
| Eclipse Cleanup ID | Value |
|---|---|
MYCleanUpConstants.USEFUNCTIONALLOOP_CLEANUP |
true (enable this feature) |
Usage:
- Via Eclipse Clean Up... under the appropriate cleanup category
- Via JDT Batch tooling or Save Actions
- Does not preserve external loop-scoped variables (e.g., index tracking, multiple accumulators)
- Cannot convert control structures with
return,break,continue label, orthrow - Does not support loops producing
Map<K,V>outputs or grouping patterns (future feature) - Does not merge consecutive filters/maps (could be optimized in future versions)
The Functional Converter Cleanup:
- Applies safe and proven transformations across 21 tested patterns
- Targets common loop structures found in legacy codebases
- Modernizes Java 5/6/7-style loops to Java 8 stream-based idioms
- Uses an extensive test suite for coverage and correctness
- Maintains semantic safety by excluding complex patterns
Further Reading:
- Implementation Details: ARCHITECTURE.md β In-depth architecture documentation
- Test Coverage:
Java8CleanUpTest.javain thesandbox_functional_converter_testmodule - Wiki: Functional Converter β Converts
Iteratorloops to functional loops
Automates migration of legacy tests from JUnit 3 and JUnit 4 to JUnit 5 (Jupiter). Transforms test classes, methods, annotations, assertions, and lifecycle hooks to use the modern JUnit 5 API.
Key Features:
- JUnit 3 β 5: Remove
extends TestCase, convert naming conventions to annotations - JUnit 4 β 5: Update annotations (
@Beforeβ@BeforeEach,@Ignoreβ@Disabled) - Assertion parameter reordering (message-last pattern)
- Lifecycle method transformations
- Rule migration (
@Ruleβ@RegisterExtension) - Test suite conversion
Quick Example:
// Before (JUnit 3)
public class MyTest extends TestCase {
protected void setUp() throws Exception {
super.setUp();
}
public void testSomething() {
assertEquals("message", expected, actual);
}
}
// After (JUnit 5)
public class MyTest {
@BeforeEach
void setUp() {
}
@Test
void testSomething() {
assertEquals(expected, actual, "message");
}
}π Full Documentation: Plugin README | Architecture | TODO | Testing Guide
The Method Reusability Finder is an Eclipse JDT cleanup plugin that analyzes selected methods to identify potentially reusable code patterns across the codebase. It helps developers discover duplicate or similar code that could be refactored to improve code quality and maintainability.
- Code Duplication Detection: Identify similar code patterns using both token-based and AST-based analysis
- Intelligent Matching: Recognize code similarity even when variable names differ
- Eclipse Integration: Seamlessly integrate as a cleanup action in Eclipse JDT
- Performance: Efficient analysis that scales to large codebases
- Token-based similarity: Compares normalized token sequences
- AST-based similarity: Compares abstract syntax tree structures
- Variable name normalization: Ignores variable name differences
- Control flow analysis: Matches similar control structures
- Searches method bodies for inline code sequences
- Finds code that matches a target method's body
- Identifies refactoring opportunities within methods
- Analyzes semantic safety of replacements
- Detects field modifications and side effects
- Checks for complex control flow
| Component | Purpose |
|---|---|
MethodReuseFinder |
Searches project for similar methods |
MethodSignatureAnalyzer |
Analyzes and compares method signatures |
CodePatternMatcher |
AST-based pattern matching |
InlineCodeSequenceFinder |
Finds inline code sequences |
CodeSequenceMatcher |
Matches statement sequences with normalization |
VariableMapping |
Tracks variable name mappings |
MethodCallReplacer |
Generates method invocation replacement code |
SideEffectAnalyzer |
Analyzes safety of replacements |
Cleanup options are defined in MYCleanUpConstants:
METHOD_REUSE_CLEANUP- Enable/disable the cleanupMETHOD_REUSE_INLINE_SEQUENCES- Enable inline code sequence detection
This cleanup is available as part of the JDT Clean Up framework:
- Eclipse UI β Source β Clean Up
- Automated build tools using Eclipse JDT APIs
This is a new plugin currently under development. The initial implementation focuses on:
- Basic method similarity detection
- AST-based pattern matching
- Integration with Eclipse cleanup framework
See sandbox_method_reuse/TODO.md for pending features and improvements.
The XML Cleanup plugin provides automated refactoring and optimization for PDE-relevant XML files in Eclipse projects. It focuses on reducing file size while maintaining semantic integrity through XSLT transformation, whitespace normalization, and optional indentation.
- Optimize PDE XML configuration files for size and consistency
- Apply secure XSLT transformations with whitespace normalization
- Convert leading spaces to tabs (4 spaces β 1 tab)
- Provide optional indentation control (default: OFF for size reduction)
- Integrate with Eclipse workspace APIs for safe file updates
The plugin only processes PDE-relevant XML files:
Supported File Names:
plugin.xml- Eclipse plugin manifestsfeature.xml- Eclipse feature definitionsfragment.xml- Eclipse fragment manifests
Supported File Extensions:
*.exsd- Extension point schema definitions*.xsd- XML schema definitions
Supported Locations: Files must be in one of these locations:
- Project root - Files directly in project folder
- OSGI-INF - OSGi declarative services directory
- META-INF - Manifest and metadata directory
Note: All other XML files (e.g.,
pom.xml,build.xml) are ignored to avoid unintended transformations.
- Uses secure XML processing (external DTD/entities disabled)
- Preserves XML structure, comments, and content
- Default:
indent="no"- Produces compact output for size reduction - Optional:
indent="yes"- Enabled viaXML_CLEANUP_INDENTpreference
- Reduce excessive empty lines - Maximum 2 consecutive empty lines
- Leading space to tab conversion - Only at line start (not inline text)
- Converts groups of 4 leading spaces to 1 tab
- Preserves remainder spaces (e.g., 5 spaces β 1 tab + 1 space)
- Does NOT touch inline text or content nodes
- Only writes file if content actually changed
- Uses Eclipse workspace APIs (
IFile.setContents()) - Maintains file history (
IResource.KEEP_HISTORY) - Refreshes resource after update
Default Behavior (when XML_CLEANUP is enabled):
indent="no"- Compact output, no extra whitespace- Reduces file size by removing unnecessary whitespace
- Converts leading spaces to tabs
- Preserves semantic content
Optional Behavior (when XML_CLEANUP_INDENT is enabled):
indent="yes"- Minimal indentation applied- Still converts leading spaces to tabs
- Slightly larger file size but more readable
Constants (defined in MYCleanUpConstants):
XML_CLEANUP- Enable XML cleanup (default: OFF)XML_CLEANUP_INDENT- Enable indentation (default: OFF)
The plugin implements secure XML processing:
- External DTD access disabled
- External entity resolution disabled
- DOCTYPE declarations disallowed
- Secure processing mode enabled
Tab conversion is only applied to leading whitespace:
β Converted:
<element> <!-- 4 leading spaces β 1 tab -->β Not Converted:
<element attr="value with spaces"/> <!-- Inline spaces preserved -->This ensures that:
- Indentation is normalized to tabs
- XML attribute values are not modified
- Text content spacing is preserved
- Only structural whitespace is affected
This cleanup is available as part of the JDT Clean Up framework:
- Eclipse UI β Source β Clean Up
- Configure via cleanup preferences:
XML_CLEANUPandXML_CLEANUP_INDENT
- PDE Files Only: Only processes plugin.xml, feature.xml, fragment.xml, *.exsd, *.xsd
- Location Restricted: Files must be in project root, OSGI-INF, or META-INF
- Leading Tabs Only: Tab conversion only applies to leading whitespace, not inline content
- No Schema Validation: Doesn't validate against XML schemas (relies on Eclipse PDE validation)
The sandbox_xml_cleanup_test module contains comprehensive test cases for:
- Size reduction verification
- Semantic equality (using XMLUnit, ignoring whitespace)
- Idempotency (second run produces no change)
- Leading-indent-only tab conversion
- PDE file filtering accuracy
You can use the P2 update site:
https://github.com/carstenartur/sandbox/raw/main
Warning:
Use only with a fresh Eclipse installation that can be discarded after testing.
It may break your setup. Donβt say you werenβt warned...
This repository contains extensive documentation organized at multiple levels to help you understand, use, and contribute to the project.
- README.md (this file) - Project overview, build instructions, and plugin descriptions
- Build Instructions - How to build the project with Maven/Tycho
- Quickstart - Quick introduction to using the plugins
- Installation - How to install plugins in Eclipse
Each plugin has dedicated documentation in its module directory:
Documentation Structure per Plugin:
- README.md - Quick start guide, features overview, and usage examples
- ARCHITECTURE.md - Design overview, implementation details, patterns used
- TODO.md - Pending features, known issues, future enhancements
- TESTING.md (where applicable) - Test organization, coverage, and running instructions
- HelperVisitor API Test Suite - Comprehensive guide to testing with HelperVisitor API
- JUnit Migration Test Suite - Test organization for JUnit 4β5 migration
- JUnit Migration Implementation Tracking - Missing features and bugs in migration cleanup
- CODE_OF_CONDUCT.md - Community guidelines
- SECURITY.md - Security policy and vulnerability reporting
- CONTRIBUTING.md - How to contribute to this project
- LICENSE.txt - Eclipse Public License 2.0
- TRIGGERPATTERN.md - Pattern matching engine documentation
- Eclipse Version Configuration - How to update Eclipse versions
- Release Process - How to create releases
When contributing to this project, please maintain documentation quality:
-
Plugin Requirements: All plugin directories SHOULD contain:
README.md- Quick start guide with features and usage examplesARCHITECTURE.md- Design and implementation overviewTODO.md- Open tasks and future work
-
Navigation Headers: All plugin documentation files include navigation headers linking to:
- Main README (this file)
- Plugin's own README (for ARCHITECTURE and TODO files)
- Sibling documentation files (README β ARCHITECTURE β TODO)
-
Update Documentation: When making code changes:
- Update
README.mdif features or usage changes - Update
ARCHITECTURE.mdif design changes - Update
TODO.mdwhen completing tasks or identifying new ones - Update main README if adding/removing plugins
- Update
-
Test Documentation: Test modules with substantial test organization should include:
TESTING.md- Test structure and organizationTODO_TESTING.md(if applicable) - Implementation tracking for features being tested
By Topic:
- Building & Setup: Build Instructions, Eclipse Version Configuration
- Code Coverage: Coverage Deployment - JaCoCo reports on GitHub Pages
- Plugin Usage: See Projects section for detailed descriptions of each plugin
- Architecture: Check
ARCHITECTURE.mdin each plugin directory - Testing: HelperVisitor API, JUnit Migration
- Contributing: Contributing, Release Process
By File Location:
- Root level: Project-wide documentation (this README, CODE_OF_CONDUCT, SECURITY)
- Plugin directories (
sandbox_*/): Plugin-specific ARCHITECTURE.md and TODO.md - Test directories (
sandbox_*_test/): Test-specific TESTING.md and TODO_TESTING.md
Contributions are welcome! This is an experimental sandbox project for testing Eclipse JDT cleanup implementations.
- Fork the repository on GitHub
- Create a feature branch from
main(the default branch):git checkout -b feature/my-new-cleanup
- Make your changes following the existing code structure and conventions
- Test your changes thoroughly:
mvn -Pjacoco verify
- Commit your changes with clear commit messages:
git commit -m "feat: add new cleanup for XYZ pattern" - Push to your fork and create a Pull Request targeting the
mainbranch
- Follow existing code patterns and cleanup structures
- Add comprehensive test cases for new cleanups
- Update documentation (README, architecture.md, todo.md) as needed
- Ensure SpotBugs, CodeQL, and all tests pass
- Keep changes focused and minimal
Found a bug or have a feature request? Please open an issue on GitHub with:
- Clear description of the problem or suggestion
- Steps to reproduce (for bugs)
- Expected vs. actual behavior
- Eclipse and Java version information
Note: This project primarily serves as an experimental playground. Features that prove stable and useful may be contributed upstream to Eclipse JDT.
This section describes how to create and publish a new release of the Sandbox project using the automated release workflow.
- Write access to the repository
- All tests passing on the
mainbranch - Decide on the release version number (e.g.,
1.2.2) - Decide on the next SNAPSHOT version (e.g.,
1.2.3-SNAPSHOT)
The release process is fully automated through GitHub Actions. To create a release:
- Go to the GitHub Actions tab
- Select "Release Workflow" from the workflows list
- Click "Run workflow" button
- Fill in the required inputs:
- Release version: The version to release (e.g.,
1.2.2) - Next SNAPSHOT version: The next development version (e.g.,
1.2.3-SNAPSHOT)
- Release version: The version to release (e.g.,
- Click "Run workflow" to start the automated release process
The workflow performs all release steps automatically:
- β
Validates inputs to ensure release_version has no
-SNAPSHOTsuffix and next_snapshot_version includes it - β
Updates version in all
pom.xml,MANIFEST.MF,feature.xml, and*.productfiles usingtycho-versions-pluginfor all modules exceptsandbox-functional-converter-core, which maintains independent versioning - β
Verifies that no SNAPSHOT references remain (except in
sandbox-functional-converter-core) - β Commits the release version changes
- β Builds and verifies the release
- β
Creates and pushes git tag (
vX.Y.Z) immediately - β
Creates and pushes maintenance branch (
maintenance/X.Y.x) immediately for potential backports - β Generates release notes from closed issues since the last release
- β Creates GitHub release with auto-generated notes
- β
Deploys the P2 update site to GitHub Pages at
https://carstenartur.github.io/sandbox/releases/X.Y.Z/ - β Updates composite metadata to include the new release
- β Bumps version to the next SNAPSHOT version
- β
Commits and pushes the SNAPSHOT version back to
main - β Reminds to update Eclipse Marketplace listing
After the workflow completes successfully:
-
Verify the release:
- Check the Releases page for the new release
- Verify the update site is available at
https://carstenartur.github.io/sandbox/releases/X.Y.Z/
-
Update Eclipse Marketplace (if applicable):
- Go to Eclipse Marketplace
- Update the listing with the new update site URL
-
Test the release:
- Install the plugins from the new update site in a clean Eclipse installation
- Verify core functionality works as expected
The automated workflow requires two inputs:
-
release_version(required):- The version number to release (e.g.,
1.2.2) - Must NOT include
-SNAPSHOTsuffix - Should follow Semantic Versioning
- The version number to release (e.g.,
-
next_snapshot_version(required):- The next development version (e.g.,
1.2.3-SNAPSHOT) - MUST include
-SNAPSHOTsuffix - Typically the next patch, minor, or major version
- The next development version (e.g.,
To release version 1.2.2 and prepare for 1.2.3-SNAPSHOT:
- Navigate to Actions β Release Workflow β Run workflow
- Enter
release_version:1.2.2 - Enter
next_snapshot_version:1.2.3-SNAPSHOT - Click "Run workflow"
- Monitor the workflow progress in the Actions tab
- Once complete, the main branch will be at
1.2.3-SNAPSHOT, ready for development
This project follows Semantic Versioning:
- MAJOR version (X.0.0): Incompatible API changes
- MINOR version (0.X.0): New functionality in a backward-compatible manner
- PATCH version (0.0.X): Backward-compatible bug fixes
Each release produces:
- Eclipse Product: Installable Eclipse IDE with bundled plugins (
sandbox_product/target) - P2 Update Site: For installing plugins into existing Eclipse (
sandbox_web/target) - WAR File: Web-deployable update site
- Maven Artifacts: Published to GitHub Packages
Build fails during release:
- Ensure all tests pass locally:
mvn clean verify -Pjacoco - Check Java version:
java -version(must be 21+) - Verify Maven version:
mvn -version(3.9.x recommended)
GitHub Actions workflow fails:
- Check workflow run logs in the Actions tab
- Ensure the tag was pushed correctly:
git ls-remote --tags origin - Verify permissions for GitHub Packages publishing
This project is licensed under the Eclipse Public License 2.0 (EPL-2.0).
See the LICENSE.txt file for the full license text.
The Eclipse Public License (EPL) is a free and open-source software license maintained by the Eclipse Foundation. Key points:
- β Commercial use allowed
- β Modification allowed
- β Distribution allowed
- β Patent grant included
β οΈ Disclose source for modificationsβ οΈ License and copyright notice required
For more information, visit: https://www.eclipse.org/legal/epl-2.0/
Copyright Β© 2021-2025 Carsten Hammer and contributors