Champollion strictly implements the Jakarta https://jakarta.ee/specifications/jsonp/2.1/ and https://jakarta.ee/specifications/jsonb/3.0/ specs. Migrating from Parsson or Yasson is essentially a Maven coordinate swap. Migrating from Jackson requires rewriting proprietary annotations into their standard Jakarta equivalents.
From Parsson (Eclipse JSON-P RI)
Parsson is the Eclipse Reference Implementation of JSON-P 2.1. The swap is mechanical.
Maven
<!-- Before -->
<dependency>
<groupId>org.eclipse.parsson</groupId>
<artifactId>parsson</artifactId>
<version>1.1.7</version>
</dependency>
<!-- After -->
<dependency>
<groupId>io.vidocq.champollion</groupId>
<artifactId>champollion-jsonp</artifactId>
<version>${champollion.version}</version>
</dependency>
Application code
Nothing changes. Application code only uses jakarta.json.* (the spec) — JsonProvider resolution goes through ServiceLoader.
Expected performance
Since the P13 parser work (single-pass number scan + bit-stack state machine, run of 2026-06-12), Champollion beats Parsson on the pull parser for MEDIUM (1.17×) and LARGE (1.08×) payloads; only SMALL remains behind (0.66×, dominated by per-parse fixed costs — Parsson pools its buffers). A pure event drain also allocates ~22× less than Parsson. Details and raw JMH numbers in BENCH.md.
From Yasson (Eclipse JSON-B RI)
Yasson is the Eclipse Reference Implementation of JSON-B 3.0.
Maven
<!-- Before -->
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>3.0.4</version>
</dependency>
<!-- After -->
<dependency>
<groupId>io.vidocq.champollion</groupId>
<artifactId>champollion-jsonb</artifactId>
<version>${champollion.version}</version>
</dependency>
Enable static codegen (recommended)
To benefit from reflection-free bindings (Champollion’s identity-defining strength):
-
Add the APT in
providedscope:<dependency> <groupId>io.vidocq.champollion</groupId> <artifactId>champollion-codegen-apt</artifactId> <version>${champollion.version}</version> <scope>provided</scope> </dependency> -
Annotate the records to bind with
@JsonbStatic(io.vidocq.champollion.jsonb.spi) — it is the APT’s trigger; un-annotated types keep using runtime introspection. -
Recompile. The runtime auto-discovers each
<Type>$$Bindingvia ServiceLoader. To verify which types are statically bound, inspect theMETA-INF/services/io.vidocq.champollion.jsonb.spi.JsonbBindingentries in the produced jar.
Expected performance
Champollion beats Yasson on reads (~40% faster on MEDIUM fromJson) and sits at ~Yasson level on writes (runtime mode, BENCH.md run of 2026-06-12). Static codegen mode removes the introspection warmup on top — see BENCH.md §7.
From Jackson
Jackson does not implement Jakarta JSON-B — it has its own annotation universe (@JsonProperty, @JsonIgnore, @JsonFormat, @JsonInclude…). Migration requires rewriting annotations.
Mapping table
| Jackson | Jakarta JSON-B (Champollion) | Notes |
|---|---|---|
|
|
Direct. |
|
|
Direct. |
|
|
For |
|
|
Different granularity. |
|
|
Different signatures (see below). |
|
|
Idem. |
|
|
Records: no annotation required. |
|
|
New in JSON-B 3.0. |
|
|
Global config rather than annotation. |
|
|
|
|
|
Likewise on read: |
Custom serializer
// Jackson
public class MyJsonSer extends JsonSerializer<Money> {
@Override public void serialize(Money m, JsonGenerator g, SerializerProvider p) throws IOException {
g.writeString(m.amount() + " " + m.currency());
}
}
// Champollion (Jakarta JSON-B)
public final class MyJsonbSer implements JsonbSerializer<Money> {
@Override public void serialize(Money m, JsonGenerator g, SerializationContext ctx) {
g.write(m.amount() + " " + m.currency());
}
}
The JsonGenerator on the JSON-B side is the Jakarta JSON-P one — not Jackson’s ObjectGenerator. No checked IOException, fluent.
Expected performance
Jackson remains 3-4× faster than Champollion on binding (15 years of POJO-specific optimizations + bytecode codegen of accessors). However, Jackson is not a Jakarta JSON-B implementation — migration is only meaningful to align with the Jakarta specs and benefit from standard portability.
From Gson, Genson, JSON-Simple…
Same principles as Jackson: these libs are proprietary and migration to Champollion (= Jakarta JSON-B) requires replacing their annotations with their standard equivalents. Gson, Genson, etc. do not implement Jakarta JSON-B and are not ServiceLoader-replaceable.
Validating the migration
Champollion guards its own two modes with a differential suite — for each covered type, the APT-generated binding must produce byte-identical JSON to the introspective runtime:
# Runtime vs static-codegen differential suite (in the Champollion repo)
mvn -ntp -pl champollion-codegen-apt -Dtest=DifferentialBindingTest test
For your own project, apply the same idea against the legacy lib: keep Champollion alongside it for one test cycle, compare the emitted JSON in your tests, then switch definitively after output validation.