JCS
Juneau supports converting arbitrary POJOs to canonical JSON per RFC 8785 (JCS - JSON Canonicalization Scheme) using a native serializer. JCS produces a deterministic, byte-for-byte representation suitable for cryptographic operations such as hashing and digital signing.
The JcsSerializer converts POJOs to canonical JSON. The Jcs marshaller pairs it with JsonParser for full round-trip support (JCS output is valid JSON).
JCS support is included in juneau-marshall.
| Maven | |
|---|
Quick Start
// A simple bean
public class Person {
public String name;
public int age;
public Person() {}
public Person(String name, int age) { this.name = name; this.age = age; }
}
// Serialize to canonical JSON
Person alice = new Person("Alice", 30);
String canonical = Jcs.of(alice);
Produces:
{"age":30,"name":"Alice"}
Parsing
JCS output is valid JSON. Use the standard JsonParser or the Jcs marshaller:
// Parse canonical JSON into a bean
Person parsed = Jcs.to(canonical, Person.class);
// Or use JsonParser directly
Person also = JsonParser.DEFAULT.read(canonical, Person.class);
Canonicalization Rules (RFC 8785)
- No whitespace - Output is a single contiguous line.
- Sorted properties - Object keys sorted by UTF-16 code unit order, recursively.
- ECMAScript numbers - Shortest representation, no trailing zeros, lowercase
e,+for positive exponents. - Strings - Control chars escaped; non-ASCII emitted as literal UTF-8.
- Array order - Preserved (not sorted).
Bean-to-JCS Mapping
- Maps and beans → Canonical JSON objects (keys sorted)
- Collections and arrays → JSON arrays (order preserved)
- Numbers → ECMAScript-compatible strings
- Strings → JSON strings with JCS escaping
- Booleans →
true/false - Null →
null - ObjectSwaps → Applied for dates, enums, etc.
Media Types
- Produces:
application/json(canonical form) - Accepts: Standard JSON (use
JsonParser)
REST Integration
// JCS is included in BasicUniversalConfig
@Rest
public class MyResource extends RestServlet implements BasicUniversalConfig { ... }
Limitations
- NaN and Infinity -
Double.NaN,Double.POSITIVE_INFINITY, andDouble.NEGATIVE_INFINITYare rejected and throwSerializeException. - Lone surrogates - Strings containing unpaired UTF-16 surrogate code units throw
SerializeException. - BigDecimal/BigInteger - Values beyond IEEE 754 double precision may lose precision or throw.
- No separate media type - Output is
application/json. Use JCS explicitly by class reference, not content negotiation.
Use Cases
- Digital signatures - Canonical form ensures identical bytes for signers and verifiers.
- Content hashing - Deterministic output for SHA-256 or other hashes.
- JWK Thumbprint - Compatible with RFC 7638 and similar schemes.
- Stable serialization - Same object always produces the same string.
Annotations
@JcsConfig applies to JcsSerializer only
(see Context Annotations). Its only attribute is rank, since JCS uses a fixed canonical
output with no tunable options. JCS has no @Jcs data annotation or @JcsApply.
- RFC 8785 — JSON Canonicalization Scheme for the full specification.
- Marshallers for the marshaller API overview.
- JSON Methodology for JSON type mapping.