Skip to main content

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
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-marshall</artifactId>
<version>${juneau.version}</version>
</dependency>

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, and Double.NEGATIVE_INFINITY are rejected and throw SerializeException.
  • 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.

See Also