Releases: aether-framework/aether-datafixers
🚀 Aether Datafixers v0.5.0 — API Freeze & Release Readiness
The API freeze release with stabilized public interfaces, comprehensive validation tooling, extended codec support, and full multi-format integration across all modules.
🎯 Highlights in v0.5.0
- ✅ API Freeze — Public API is now stable; no breaking changes expected before v1.0.0
- ✅ Schema Validation Integration — Full
MigrationAnalyzerintegration for fix coverage validation - ✅ MigrationService.withOps() — Custom
DynamicOpssupport for format conversion during migrations - ✅ Extended Codec Support — Multi-format DynamicOps integration for CLI, Testkit and Spring Boot modules
- ✅ Functional Tests Module — New
aether-datafixers-functional-testswith E2E and integration tests - ✅ Comprehensive Documentation — Complete documentation suite covering all modules and features
📦 Installation
Tip
All Aether artifacts are available on Maven Central — no extra repository required.
Maven
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-core</artifactId>
<version>0.5.0</version>
</dependency>Using the BOM
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-bom</artifactId>
<version>0.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- No version needed -->
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-core</artifactId>
</dependency>
</dependencies>Gradle (Groovy)
dependencies {
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core:0.5.0'
// Or with BOM:
implementation platform('de.splatgames.aether.datafixers:aether-datafixers-bom:0.5.0')
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core'
}Gradle (Kotlin)
dependencies {
implementation("de.splatgames.aether.datafixers:aether-datafixers-core:0.5.0")
// Or with BOM:
implementation(platform("de.splatgames.aether.datafixers:aether-datafixers-bom:0.5.0"))
implementation("de.splatgames.aether.datafixers:aether-datafixers-core")
}🆕 What's New
🔍 SchemaValidator Fix Coverage Integration
The SchemaValidator.validateFixCoverage() method now performs actual coverage analysis using MigrationAnalyzer:
ValidationResult result = SchemaValidator.forBootstrap(bootstrap)
.validateFixCoverage()
.validate();
if (result.hasWarnings()) {
for (ValidationIssue issue : result.warnings()) {
System.out.println("Missing fix: " + issue.message());
// e.g., "Missing DataFix for type 'player' field 'health': FIELD_ADDED"
}
}Features:
- Automatically analyzes the full version range from schema registry
- Detects missing DataFixes for schema changes (field additions, removals, type changes)
- Reports field-level coverage gaps with detailed context
- Integrates seamlessly with existing validation pipeline
🔄 MigrationService.withOps() Support
The Spring Boot MigrationService now fully supports custom DynamicOps for format conversion:
// Convert input data to Jackson YAML format during migration
MigrationResult result = migrationService
.migrate(gsonData)
.from(100)
.to(200)
.withOps(JacksonYamlOps.INSTANCE) // Now fully functional!
.execute();
// Result data is now in Jackson YAML format
Dynamic<JsonNode> yamlResult = (Dynamic<JsonNode>) result.getData();Use Cases:
- Convert between serialization formats during migration
- Normalize data to a specific format for downstream processing
- Work with format-specific features (e.g., YAML anchors, TOML tables)
🔌 Extended Codec Support for CLI & Testkit
Full multi-format DynamicOps integration for the CLI and Testkit modules:
CLI Format Handlers:
| Format ID | Library | Data Type | File Extensions |
|---|---|---|---|
json-gson |
Gson | JsonElement |
.json |
json-jackson |
Jackson | JsonNode |
.json |
yaml-snakeyaml |
SnakeYAML | Object |
.yaml, .yml |
yaml-jackson |
Jackson YAML | JsonNode |
.yaml, .yml |
toml-jackson |
Jackson TOML | JsonNode |
.toml |
xml-jackson |
Jackson XML | JsonNode |
.xml |
Testkit Factory Methods:
// All formats now supported in TestData
Dynamic<JsonElement> gson = TestData.gson().object().put("key", "value").build();
Dynamic<JsonNode> jackson = TestData.jacksonJson().object().put("key", "value").build();
Dynamic<Object> yaml = TestData.snakeYaml().object().put("key", "value").build();
Dynamic<JsonNode> yamlJ = TestData.jacksonYaml().object().put("key", "value").build();
Dynamic<JsonNode> toml = TestData.jacksonToml().object().put("key", "value").build();
Dynamic<JsonNode> xml = TestData.jacksonXml().object().put("key", "value").build();🧪 Functional Tests Module
New aether-datafixers-functional-tests module with comprehensive E2E and integration tests:
| Test Category | Description |
|---|---|
| Cross-Format Migration | Validate migrations work identically across all DynamicOps |
| Error Recovery | Test graceful handling of malformed data and fix failures |
| Field Transformations | E2E tests for rename, add, remove, and restructure operations |
Run integration tests with:
mvn verify -Pit📋 Module Overview
| Module | Description |
|---|---|
aether-datafixers-api |
Core interfaces and API contracts (stable) |
aether-datafixers-core |
Default implementations |
aether-datafixers-codec |
DynamicOps for JSON, YAML, TOML, XML |
aether-datafixers-testkit |
Testing utilities with fluent API + multi-format support |
aether-datafixers-cli |
Command-line interface with multi-format handlers |
aether-datafixers-schema-tools |
Schema analysis, validation, and diffing |
aether-datafixers-spring-boot-starter |
Spring Boot 3.x auto-configuration |
aether-datafixers-examples |
Practical usage examples |
aether-datafixers-functional-tests |
E2E and integration tests |
aether-datafixers-bom |
Bill of Materials for version management |
📝 Changelog
New in 0.5.0
SchemaValidator.validateFixCoverage()now performs actual coverage analysis viaMigrationAnalyzerMigrationService.withOps()fully implemented for format conversion during migrations- Extended codec support: CLI format handlers for YAML, TOML, XML
- Extended codec support: Testkit factory methods for all DynamicOps implementations
- New
aether-datafixers-functional-testsmodule with comprehensive E2E and IT tests - Cross-format migration tests (Gson, Jackson JSON, Jackson YAML, SnakeYAML, TOML, XML)
- Error recovery integration tests with graceful failure handling
- Field transformation E2E tests (rename, add, group operations)
- API stabilization: public interfaces frozen for v1.0.0
- Comprehensive documentation updates across all modules
Deprecations (removal planned for v1.0.0)
de.splatgames.aether.datafixers.codec.gson.GsonOps— Usecodec.json.gson.GsonOpsde.splatgames.aether.datafixers.codec.jackson.JacksonOps— Usecodec.json.jackson.JacksonJsonOpsfor JSON, or the format-specific classes (JacksonYamlOps,JacksonTomlOps,JacksonXmlOps)TestData.jackson()— UseTestData.jacksonJson()instead
Full Changelog: v0.4.0...v0.5.0
🔄 Migration from v0.4.0
Breaking Changes
None. v0.5.0 is fully backward compatible with v0.4.0.
Deprecated API Updates
If using deprecated wrapper classes, update imports:
// Old (deprecated)
import de.splatgames.aether.datafixers.codec.gson.GsonOps;
// New
import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;🗺️ Roadmap
v1.0.0 (next)
- Stable Release — Production-ready with semantic versioning guarantees
- Performance Benchmarks — Published benchmark suite
- Extended Documentation — Video tutorials and cookbook examples
📜 License
MIT — see LICENSE.
🚀 Aether Datafixers v0.4.0 — Spring Boot Integration & Multi-Format DynamicOps
Spring Boot auto-configuration with fluent MigrationService API, Actuator integration, and comprehensive multi-format support for YAML, TOML, and XML.
🎯 Highlights in v0.4.0
- ✅ Spring Boot Starter — New
aether-datafixers-spring-boot-startermodule with auto-configuration, fluentMigrationServiceAPI, multi-domain support, Actuator health/info/endpoints, and Micrometer metrics - ✅ Multi-Format DynamicOps — New DynamicOps implementations for YAML (SnakeYAML, Jackson), TOML (Jackson), and XML (Jackson)
- ✅ Package Restructuring — Format-first package organization (
codec.json.gson,codec.yaml.jackson, etc.) - ✅ Comprehensive Documentation — New Spring Boot integration docs and codec format guides
📦 Installation
Tip
All Aether artifacts are available on Maven Central — no extra repository required.
Maven
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-core</artifactId>
<version>0.4.0</version>
</dependency>Using the BOM
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-bom</artifactId>
<version>0.4.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- No version needed -->
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-core</artifactId>
</dependency>
</dependencies>Gradle (Groovy)
dependencies {
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core:0.4.0'
// Or with BOM:
implementation platform('de.splatgames.aether.datafixers:aether-datafixers-bom:0.4.0')
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core'
}Gradle (Kotlin)
dependencies {
implementation("de.splatgames.aether.datafixers:aether-datafixers-core:0.4.0")
// Or with BOM:
implementation(platform("de.splatgames.aether.datafixers:aether-datafixers-bom:0.4.0"))
implementation("de.splatgames.aether.datafixers:aether-datafixers-core")
}🆕 What's New
🍃 Spring Boot Starter Module
New module aether-datafixers-spring-boot-starter for seamless Spring Boot 3.x integration:
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-spring-boot-starter</artifactId>
<version>0.4.0</version>
</dependency>Key Features:
| Feature | Description |
|---|---|
| 🔧 Auto-Configuration | Automatic DataFixer bean creation from DataFixerBootstrap beans |
| 🔄 MigrationService | Fluent API: .migrate(data).from(100).to(200).execute() |
| 🏷️ Multi-Domain | Multiple DataFixers with @Qualifier and .usingDomain("game") |
| 💚 Actuator | Health indicator, info contributor, /actuator/datafixers endpoint |
| 📊 Metrics | Micrometer counters, timers, and distribution summaries |
| ⚡ Async | CompletableFuture support via .executeAsync() |
Quick Start:
@Configuration
public class DataFixerConfig {
@Bean
public DataFixerBootstrap gameBootstrap() {
return new GameDataBootstrap();
}
}
@Service
public class GameService {
private final MigrationService migrationService;
public Dynamic<?> migrateData(Dynamic<?> data, int fromVersion) {
return migrationService
.migrate(data)
.from(fromVersion)
.toLatest()
.execute()
.getData();
}
}Configuration Properties:
aether:
datafixers:
enabled: true
default-format: gson # gson | jackson | jackson_yaml | snakeyaml | jackson_toml | jackson_xml
default-current-version: 200
domains:
game:
current-version: 200
primary: true
actuator:
include-schema-details: true
metrics:
timing: true
counting: true🔌 Multi-Format DynamicOps
New DynamicOps implementations in the codec module:
| Format | Implementation | Data Type | Library |
|---|---|---|---|
| JSON | GsonOps |
JsonElement |
Gson |
| JSON | JacksonJsonOps |
JsonNode |
Jackson |
| YAML | SnakeYamlOps |
Object |
SnakeYAML |
| YAML | JacksonYamlOps |
JsonNode |
Jackson YAML |
| TOML | JacksonTomlOps |
JsonNode |
Jackson TOML |
| XML | JacksonXmlOps |
JsonNode |
Jackson XML |
Example:
// YAML with SnakeYAML (native Java types)
Dynamic<Object> yaml = new Dynamic<>(SnakeYamlOps.INSTANCE, yamlData);
// TOML with Jackson
Dynamic<JsonNode> toml = new Dynamic<>(JacksonTomlOps.INSTANCE, tomlData);
// Cross-format conversion
Dynamic<JsonElement> json = yaml.convert(GsonOps.INSTANCE);⚠️ Breaking Change: Package Restructuring
The codec module now uses format-first package organization:
Old:
import de.splatgames.aether.datafixers.codec.gson.GsonOps;
import de.splatgames.aether.datafixers.codec.jackson.JacksonOps;New:
import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;
import de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps;
import de.splatgames.aether.datafixers.codec.yaml.snakeyaml.SnakeYamlOps;
import de.splatgames.aether.datafixers.codec.yaml.jackson.JacksonYamlOps;
import de.splatgames.aether.datafixers.codec.toml.jackson.JacksonTomlOps;
import de.splatgames.aether.datafixers.codec.xml.jackson.JacksonXmlOps;📝 Changelog
New in 0.4.0
- Spring Boot Starter with auto-configuration and MigrationService
- Actuator health indicator, info contributor, and custom endpoint
- Micrometer metrics for migration success/failure/duration
- Multi-domain DataFixer support with
@Qualifier - SnakeYamlOps for YAML (native Java types)
- JacksonYamlOps for YAML (Jackson dataformat)
- JacksonTomlOps for TOML
- JacksonXmlOps for XML
- Format-first package restructuring in codec module
- Comprehensive Spring Boot and codec documentation
Full Changelog: v0.3.0...v0.4.0
🗺️ Roadmap (next)
- v0.5.0 (API freeze candidate)
- API stabilization pass — Naming/packaging cleanup + deprecations completed
- Compatibility checks in CI — Binary/source compatibility guardrails for public API
- Hardened error model — Consistent exception types + structured error details
- Release readiness — Final review of docs/examples against frozen API
📜 License
MIT — see LICENSE.
🚀 Aether Datafixers v0.3.0 — CLI, Schema Tools, and Convention Validation
Command-line interface for batch migrations, schema analysis tools, and naming convention validation.
🎯 Highlights in v0.3.0
- ✅ CLI Module — New
aether-datafixers-climodule for migrating and validating data files from the command line with batch processing and reports. - ✅ Schema Tools Module — New
aether-datafixers-schema-toolsmodule for schema diffing, migration analysis, validation, and type introspection. - ✅ Fix Coverage Analysis — Detect schema changes without corresponding DataFixes to ensure complete migration coverage.
- ✅ Convention Checking — Enforce naming conventions for types, fields, schema classes, and fix classes.
📦 Installation
Tip
All Aether artifacts are available on Maven Central — no extra repository required.
Maven
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-core</artifactId>
<version>0.3.0</version>
</dependency>Using the BOM
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-bom</artifactId>
<version>0.3.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- No version needed -->
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-core</artifactId>
</dependency>
</dependencies>Gradle (Groovy)
dependencies {
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core:0.3.0'
// Or with BOM:
implementation platform('de.splatgames.aether.datafixers:aether-datafixers-bom:0.3.0')
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core'
}Gradle (Kotlin)
dependencies {
implementation("de.splatgames.aether.datafixers:aether-datafixers-core:0.3.0")
// Or with BOM:
implementation(platform("de.splatgames.aether.datafixers:aether-datafixers-bom:0.3.0"))
implementation("de.splatgames.aether.datafixers:aether-datafixers-core")
}🆕 What's New
🖥️ CLI Module
New module aether-datafixers-cli for command-line data migration:
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-cli</artifactId>
<version>0.3.0</version>
</dependency>Commands:
| Command | Description |
|---|---|
migrate |
Migrate data files from one schema version to another |
validate |
Check if files need migration without modifying them |
info |
Display version info, available formats, and bootstrap details |
Features:
- Batch processing of multiple files with shell glob expansion
- Auto-detection of source version from configurable data field path
- In-place file modification with automatic
.bakbackup - Output to stdout, file, or directory
- Pretty-printed or compact JSON output
- Migration reports in text or JSON format
- Verbose mode with detailed progress and stack traces
- CI/CD friendly exit codes (0=success, 1=error, 2=migration needed)
Example:
# Migrate a single file
aether-cli migrate --from 100 --to 200 --type player --bootstrap com.example.MyBootstrap input.json
# Migrate with auto-detected version
aether-cli migrate --to 200 --type player --version-field dataVersion --bootstrap com.example.MyBootstrap input.json
# Validate files (check without modifying)
aether-cli validate --to 200 --type player --bootstrap com.example.MyBootstrap *.json
# Show available formats and bootstrap info
aether-cli info --formats
aether-cli info --bootstrap com.example.MyBootstrap🔧 Schema Tools Module
New module aether-datafixers-schema-tools for schema analysis and validation:
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-schema-tools</artifactId>
<version>0.3.0</version>
</dependency>Schema Diffing
Compare schemas between versions to see what changed:
SchemaDiff diff = SchemaDiffer.compare(schemaV1, schemaV2)
.includeFieldLevel(true)
.diff();
// Check results
diff.addedTypes(); // Types new in schemaV2
diff.removedTypes(); // Types removed from schemaV1
diff.commonTypes(); // Types in both schemas
diff.typeDiffs(); // Field-level changes for common typesMigration Analysis
Analyze migration paths and detect coverage gaps:
FixCoverage coverage = MigrationAnalyzer.forBootstrap(bootstrap)
.from(100).to(200)
.analyzeCoverage();
// Find schema changes without DataFixes
for (CoverageGap gap : coverage.gaps()) {
System.out.println("Missing fix for: " + gap.type() + " (" + gap.reason() + ")");
}
// Detect orphan fixes (fixes without schema changes)
coverage.orphanFixes();Schema Validation
Validate schema structure and naming conventions:
ValidationResult result = SchemaValidator.forBootstrap(bootstrap)
.validateStructure()
.validateConventions(ConventionRules.STRICT)
.validate();
// Check for issues
for (ValidationIssue issue : result.issues()) {
System.out.println(issue.severity() + ": " + issue.message());
}Convention Checking
Enforce naming conventions:
ConventionChecker checker = ConventionChecker.withRules(ConventionRules.builder()
.typeNamePattern(Pattern.compile("[a-z][a-z0-9_]*")) // snake_case types
.fieldNamePattern(Pattern.compile("[a-z][a-zA-Z0-9]*")) // camelCase fields
.schemaClassPrefix("Schema") // Schema100, Schema200
.fixClassSuffix("Fix") // PlayerNameFix, PositionFix
.build());
List<ValidationIssue> issues = checker.check(bootstrap);Type Introspection
Inspect type structures programmatically:
TypeStructure structure = TypeIntrospector.introspect(type);
// Get all fields with their paths
for (FieldInfo field : structure.fields()) {
System.out.println(field.path() + " : " + field.typeKind());
}
// Compare structures
boolean equal = TypeIntrospector.structurallyEqual(type1, type2);📝 Changelog
New in 0.3.0
- CLI module with migrate, validate, and info commands
- Schema Tools module with diffing, analysis, validation, and introspection
- Fix coverage analysis to detect missing DataFixes
- Convention checking for type, field, and class names
- Format handler SPI with Gson and Jackson implementations
- Comprehensive documentation updates
Full Changelog: v0.2.0...v0.3.0
🗺️ Roadmap (next)
-
v0.4.0
- Spring Boot integration — Auto-configuration for DataFixer in Spring apps
- Extra ops modules — Optional YAML/TOML support (format adapters)
- Debug utilities — Pretty printers / tree diff for Dynamic structures (dev-facing)
-
v0.5.0 (API freeze candidate)
- API stabilization pass — Naming/packaging cleanup + deprecations completed
- Compatibility checks in CI — Binary/source compatibility guardrails for public API
- Hardened error model — Consistent exception types + structured error details
- Release readiness — Final review of docs/examples against frozen API
📜 License
MIT — see LICENSE.
🚀 Aether Datafixers v0.2.0 — Testkit, Extended Rules, Diagnostics, and Performance
Extended rules, testkit module, migration diagnostics, and high-performance APIs.
🎯 Highlights in v0.2.0
- ✅ Testkit Module — New
aether-datafixers-testkitmodule with fluent test data builders, custom AssertJ assertions, and test harnesses for DataFix, Schema, and migration testing. - ✅ Extended Rewrite Rules — Convenience methods for batch operations, field grouping/flattening, path-based operations, and conditional rules.
- ✅ Migration Diagnostics — Opt-in diagnostic system for structured reports with timing, snapshots, and warnings.
- ✅ High-Performance APIs — Batch transformations and single-pass conditionals for optimized migrations.
- ✅ Performance Optimizations — Internal improvements with memoized path parsing, pre-allocated lists, and reduced allocations.
📦 Installation
Tip
All Aether artifacts are available on Maven Central — no extra repository required.
Maven
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-core</artifactId>
<version>0.2.0</version>
</dependency>Using the BOM
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-bom</artifactId>
<version>0.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- No version needed -->
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-core</artifactId>
</dependency>
</dependencies>Gradle (Groovy)
dependencies {
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core:0.2.0'
// Or with BOM:
implementation platform('de.splatgames.aether.datafixers:aether-datafixers-bom:0.2.0')
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core'
}Gradle (Kotlin)
dependencies {
implementation("de.splatgames.aether.datafixers:aether-datafixers-core:0.2.0")
// Or with BOM:
implementation(platform("de.splatgames.aether.datafixers:aether-datafixers-bom:0.2.0"))
implementation("de.splatgames.aether.datafixers:aether-datafixers-core")
}🆕 What's New
🧪 Testkit Module
New module aether-datafixers-testkit for testing migrations:
<dependency>
<groupId>de.splatgames.aether.datafixers</groupId>
<artifactId>aether-datafixers-testkit</artifactId>
<version>0.2.0</version>
<scope>test</scope>
</dependency>Features:
TestData— Fluent test data builders for Gson and JacksonAetherAssertions— Custom AssertJ assertions forDynamic,DataResult,TypedDataFixTester— Test harness for individual DataFix implementationsMigrationTester— Test harness for complete migration chainsSchemaTester— Test harness for Schema validationQuickFix— Factory methods for common fix patternsMockSchemas— Factory for mock Schema instancesRecordingContext/AssertingContext— Test contexts
Example:
// Create test data fluently
Dynamic<JsonElement> input = TestData.gson().object()
.put("name", "Alice")
.put("level", 10)
.build();
// Test a DataFix
DataFixTester.forFix(myFix)
.withInput(input)
.forType("player")
.expectOutput(expected)
.verify();
// Test a full migration chain
MigrationTester.forFixer(myFixer)
.forType(PLAYER)
.withInput(v1Data)
.from(1).to(5)
.expectOutput(v5Data)
.verify();📐 Extended Rewrite Rules
New convenience methods in Rules class:
| Rule | Purpose |
|---|---|
dynamicTransform(name, ops, fn) |
Custom Dynamic transformation |
setField(ops, field, value) |
Set field (overwrites existing) |
renameFields(ops, map) |
Batch rename multiple fields |
removeFields(ops, fields...) |
Batch remove multiple fields |
groupFields(ops, target, fields...) |
Group fields into nested object |
flattenField(ops, field) |
Flatten nested object to root |
moveField(ops, source, target) |
Move field between paths |
copyField(ops, source, target) |
Copy field (keeps original) |
transformFieldAt(ops, path, fn) |
Transform at nested path |
renameFieldAt(ops, path, newName) |
Rename at nested path |
removeFieldAt(ops, path) |
Remove at nested path |
addFieldAt(ops, path, value) |
Add at nested path |
ifFieldExists(ops, field, rule) |
Conditional on existence |
ifFieldMissing(ops, field, rule) |
Conditional on absence |
ifFieldEquals(ops, field, value, rule) |
Conditional on value |
Example:
Rules.seq(
Rules.renameFields(ops, Map.of("playerName", "name", "xp", "experience")),
Rules.groupFields(ops, "position", "x", "y", "z"),
Rules.ifFieldMissing(ops, "version", Rules.setField(ops, "version", d -> d.createInt(1)))
)📊 Migration Diagnostics
New opt-in diagnostic system for capturing structured reports:
API:
DiagnosticOptions— Configuration for diagnostic captureDiagnosticContext— Context interface for diagnostic migrationsMigrationReport— Immutable report with timing, fixes, rules, warnings, and snapshots
Features:
- Zero overhead when diagnostics are not enabled
- Configurable snapshot capture with truncation limits
- Per-fix and per-rule timing measurements
- Warning emission from DataFix implementations
Presets:
DiagnosticOptions.defaults()— Full diagnostics with snapshots and rule detailsDiagnosticOptions.minimal()— Timing only, minimal overhead
⚡ High-Performance APIs
BatchTransform:
Rules.batch(ops, batch -> batch
.rename("oldName", "newName")
.remove("deprecated")
.set("version", d -> d.createInt(2))
.transform("count", d -> d.createInt(d.asInt(0) + 1))
.addIfMissing("created", d -> d.createLong(System.currentTimeMillis()))
)Single-Pass Conditionals:
Rules.conditionalTransform(ops,
d -> d.get("type").asString("").equals("legacy"),
d -> d.set("migrated", d.createBoolean(true))
)🚀 Performance Optimizations
Internal optimizations with no API changes:
- Path parsing uses character-based parsing with memoization cache
DataFixRegistry.getFixes()pre-allocates result listDataFixerImplmoves validation to registration time- Reduced allocations in hot paths
📝 Changelog
New in 0.2.0
- Testkit module with fluent builders, assertions, and test harnesses
- Extended rewrite rules for batch, grouping, path, and conditional operations
- Migration diagnostics system with timing and snapshots
- High-performance batch transformations
- Single-pass conditional APIs
- Performance optimizations (memoization, pre-allocation)
- Comprehensive documentation updates
Full Changelog: v0.1.0...v0.2.0
🗺️ Roadmap (next)
-
v0.3.0
- CLI module — Migrate files and print/export a migration report (batch-friendly)
- Schema tooling — Runtime schema validation + diff utilities between versions
-
v0.4.0
- Spring Boot integration — Auto-configuration for DataFixer in Spring apps
- Extra ops modules — Optional YAML/TOML support (format adapters)
- Debug utilities — Pretty printers / tree diff for Dynamic structures (dev-facing)
-
v0.5.0 (API freeze candidate)
- API stabilization pass — Naming/packaging cleanup + deprecations completed
- Compatibility checks in CI — Binary/source compatibility guardrails for public API
- Hardened error model — Consistent exception types + structured error details
- Release readiness — Final review of docs/examples against frozen API
📜 License
MIT — see LICENSE.
🚀 Aether Datafixers v0.1.0 — Initial Release
Aether Datafixers is a lightweight data migration framework for the JVM.
It enables forward patching of serialized data through schema definitions and versioned fixers —
inspired by Minecraft's DataFixer Upper (DFU), with a focus on simplicity, clarity, and ease of use.
🎯 Highlights in v0.1.0
- ✅ Schema-Based Versioning
- Define data types per version with
SchemaandTypeRegistry.
- Define data types per version with
- ✅ Forward Patching
- Apply
DataFixinstances sequentially to migrate data across versions.
- Apply
- ✅ Format-Agnostic
- Work with any serialization format via
Dynamic<T>andDynamicOps<T>.
- Work with any serialization format via
- ✅ Codec System
- Bidirectional transformation between typed Java objects and dynamic representations.
- ✅ Optics
- Composable, type-safe accessors (
Lens,Prism,Iso,Traversal) for nested data structures.
- Composable, type-safe accessors (
- ✅ Type Safety
- Strong typing with
TypeReferenceidentifiers for data routing.
- Strong typing with
📦 Installation
Tip
All Aether artifacts are available on Maven Central — no extra repository required.
Maven
<dependency>
<groupId>de.splatgames.aether</groupId>
<artifactId>aether-datafixers-core</artifactId>
<version>0.1.0</version>
</dependency>Using the BOM
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.splatgames.aether</groupId>
<artifactId>aether-datafixers-bom</artifactId>
<version>0.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- No version needed -->
<dependency>
<groupId>de.splatgames.aether</groupId>
<artifactId>aether-datafixers-core</artifactId>
</dependency>
</dependencies>Gradle (Groovy)
dependencies {
implementation 'de.splatgames.aether:aether-datafixers-core:0.1.0'
// Or with BOM:
implementation platform('de.splatgames.aether:aether-datafixers-bom:0.1.0')
implementation 'de.splatgames.aether:aether-datafixers-core'
}Gradle (Kotlin)
dependencies {
implementation("de.splatgames.aether:aether-datafixers-core:0.1.0")
// Or with BOM:
implementation(platform("de.splatgames.aether:aether-datafixers-bom:0.1.0"))
implementation("de.splatgames.aether:aether-datafixers-core")
}🧰 Usage
1) Define a Bootstrap
public class MyBootstrap implements DataFixerBootstrap {
@Override
public void registerSchemas(SchemaRegistry schemas) {
// Register schema for each version
}
@Override
public void registerFixes(FixRegistrar fixes) {
// Register DataFix instances for type migrations
}
}2) Create the DataFixer
AetherDataFixer fixer = new DataFixerRuntimeFactory()
.create(currentVersion, new MyBootstrap());3) Apply Migrations
Dynamic<?> updated = fixer.update(
TypeReference.of("player"),
inputDynamic,
fromVersion,
toVersion
);📝 Changelog
New in 0.1.0
- 🎉 Initial release with complete data migration pipeline:
- Schema-based versioning with
TypeRegistry DataFixforward patching systemDynamic<T>/DynamicOps<T>format abstraction- Codec infrastructure for bidirectional serialization
- Optics system (
Lens,Prism,Iso,Affine,Traversal) SchemaDataFixbase class for schema-aware migrations- Runnable examples module demonstrating real-world usage
- Schema-based versioning with
🗺️ Roadmap (next)
-
0.2.x
- Additional codec implementations
- Extended type rewrite rules
- Performance optimizations
-
1.0.x
- Stable API surface
- Comprehensive documentation
- Production-ready release
📜 License
MIT — see LICENSE.