Extras

Contents

Beyond the main modules, Johnzon ships a set of smaller, focused artifacts.

JSON Schema

<dependency>
  <groupId>org.apache.johnzon</groupId>
  <artifactId>johnzon-jsonschema</artifactId>
  <version>${johnzon.version}</version>
</dependency>

Validates an instance against a JSON Schema:

// long live instances (@ApplicationScoped/@Singleton)
JsonObject schema = getJsonSchema();
JsonSchemaValidatorFactory factory = new JsonSchemaValidatorFactory();
JsonSchemaValidator validator = factory.newInstance(schema);

// runtime starts here
JsonObject objectToValidate = getObject();
ValidationResult result = validator.apply(objectToValidate);
// result.isSuccess(), result.getErrors(), ...

// end of runtime
validator.close();
factory.close();

Known limitations (contributions welcome): no references in the schema; no dependencies, propertyNames, if/then/else, allOf/anyOf/oneOf/not, or format validations.

JSON Logic

<dependency>
  <groupId>org.apache.johnzon</groupId>
  <artifactId>johnzon-jsonlogic</artifactId>
  <version>${johnzon.version}</version>
</dependency>
<dependency> <!-- requires an implementation of JSON-P -->
  <groupId>org.apache.johnzon</groupId>
  <artifactId>johnzon-core</artifactId>
  <version>${johnzon.version}</version>
</dependency>

Executes any JSON Logic expression:

final JohnzonJsonLogic jsonLogic = new JohnzonJsonLogic();
final JsonValue result = jsonLogic.apply(
        builderFactory.createObjectBuilder()
                .add("merge", builderFactory.createArrayBuilder()
                        .add(builderFactory.createArrayBuilder()
                                .add(1)
                                .add(2))
                        .add(3)
                        .add("4"))
                .build(),
        JsonValue.EMPTY_JSON_ARRAY);

All default operators are supported except log, so you can pick the logger implementation and name you want. Registering a custom operator:

final JohnzonJsonLogic jsonLogic = new JohnzonJsonLogic();
jsonLogic.registerOperator(
  "log",
  (logic, config, args) -> log.info(String.valueOf(logic.apply(config, args))));

The standard operator set is enriched with the JSON-P jsonpatch, JSON merge diff and JSON merge patch operators.

JSON-B Extras

<dependency>
  <groupId>org.apache.johnzon</groupId>
  <artifactId>johnzon-jsonb-extras</artifactId>
  <version>${johnzon.version}</version>
</dependency>

Extensions to JSON-B. The polymorphism extension predates the standard one. Use JSON-B 3 polymorphism instead unless you depend on the JSON format this extension generates.

For deserialization, list the potential children on the root class:

@Polymorphic.JsonChildren({
        Child1.class,
        Child2.class
})
public abstract class Root {
    public String name;
}

Bind an id on each child (without one, the simple name is used):

@Polymorphic.JsonId("first")
public class Child1 extends Root {
    public String type;
}

Then bind the serializer/deserializer on fields using the polymorphic type:

public class Wrapper {
    @JsonbTypeSerializer(Polymorphic.Serializer.class)
    @JsonbTypeDeserializer(Polymorphic.DeSerializer.class)
    public Root root;

    @JsonbTypeSerializer(Polymorphic.Serializer.class)
    @JsonbTypeDeserializer(Polymorphic.DeSerializer.class)
    public List<Root> roots;
}

The polymorphic serializer/deserializer must be bound through annotations, not through JsonbConfig.withSerializers/withDeserializers.

OSGi JAX-RS Whiteboard

Johnzon artifacts are OSGi bundles to begin with. johnzon-osgi adds integration with the OSGi JAX-RS Whiteboard and OSGi CDI Integration specifications: MessageBodyWriter/MessageBodyReader extensions for application/json (by default) to whiteboard JAX-RS applications.

Configuration goes through Configuration Admin with the pid org.apache.johnzon.jaxrs.jsonb:

PropertySynopsisTypeDefault
ignoresFully qualified class names to ignoreString[]empty
osgi.jaxrs.application.selectFilter matching the extension to whiteboard applicationsString(!(johnzon.jsonb=false)), which binds to all applications unless the application is configured with johnzon.jsonb=false
osgi.jaxrs.media.typeMedia types handledString[]application/json
throw.no.content.exception.on.empty.streamsbooleanfalse
fail.on.unknown.propertiesbooleanfalse
use.js.rangebooleanfalse
other.propertiesStringempty
ijsonbooleanfalse
encodingStringempty
binary.datastrategyStringempty
property.naming.strategyStringempty
property.order.strategyStringempty
null.valuesbooleanfalse
prettybooleanfalse
fail.on.missing.creator.valuesbooleanfalse
polymorphic.serialization.predicateStringempty
polymorphic.deserialization.predicateStringempty
polymorphic.discriminatorStringempty

Since JSON-B integrates with CDI for caching, the module also provides a jakarta.enterprise.inject.spi.Extension service with the service property osgi.cdi.extension = JavaJSONB for the OSGi CDI Integration specification.

Apache Aries CDI (the OSGi CDI Integration reference implementation) supports implicit extensions, meaning extensions a CDI bundle does not have to require explicitly. The Johnzon JSON-B CDI extension is such an extension (aries.cdi.extension.mode=implicit), so when running in Aries CDI it does not need to be required.