blob: 0587651a8ea7243bf60f0b5609d697a734cad605 [file] [view]
---
title: Modules
sidebar_position: 6
id: modules
license: |
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---
`ForyJsonModule` packages a coherent set of Fory JSON registrations into one reusable extension.
A module can be provided by a language integration, a third-party library, a framework, or an
application. Use a module when consumers should install the whole extension with one builder call;
use direct builder registration for an application-specific codec that does not need separate
distribution.
## Creating and Installing a Module
After implementing a codec such as `MoneyCodec` from the
[Custom Codecs guide](custom-codecs.md), a library can distribute its registration as a module:
```java
import org.apache.fory.json.ForyJson;
import org.apache.fory.json.ForyJsonModule;
import org.apache.fory.json.ModuleContext;
public final class MoneyJsonModule implements ForyJsonModule {
public static final MoneyJsonModule INSTANCE = new MoneyJsonModule();
private MoneyJsonModule() {}
@Override
public void install(ModuleContext context) {
context.registerCodec(Money.class, new MoneyCodec());
}
}
ForyJson json =
ForyJson.builder()
.withModule(MoneyJsonModule.INSTANCE)
.build();
```
Installation runs while `build()` creates the immutable runtime configuration. Treat a module
configuration as immutable after adding it to a builder. Registered codec instances are shared by
concurrent operations and must be thread-safe.
## Module Registrations
`ModuleContext` exposes the registrations needed by reusable integrations:
| Registration | Use |
| ---------------------------------------- | -------------------------------------------------------- |
| `registerCodec(Class, JsonValueCodec)` | One shared complete codec for an exact class |
| `registerCodec(Class, JsonCodecFactory)` | A resolver-owned complete codec for an exact class |
| `registerMixin(Class)` | An annotated Mixin for its declared target |
| `registerCodecFactory(JsonCodecFactory)` | A codec family selected from a parameterized target type |
Codec implementations and `JsonCodecFactory` behavior are documented in
[Custom Codecs](custom-codecs.md). Modules only package those registrations for installation.
Exact module registrations reject the same dedicated scalar and array types listed there; use an
occurrence annotation or semantic mapping for those representations.
Application registrations made directly on `ForyJsonBuilder` take precedence over module exact
registrations. Conflicting module registrations fail during `build()` instead of depending on
installation order.
## Kotlin Module
`ForyJsonKotlin` is the optional module for Kotlin/JVM models. Prefer its builder when an
application uses Kotlin models:
```kotlin
import org.apache.fory.json.kotlin.ForyJsonKotlin
val json = ForyJsonKotlin.builder().build()
```
This is equivalent to `ForyJson.builder().withModule(ForyJsonKotlin)`. It does not scan the
classpath or register application models. Exact application codec registrations retain normal
precedence. See [Kotlin](kotlin.md) for type tokens and optional Android minification setup.
## Module Identity
`moduleKey()` identifies the module configuration for installation conflict checking. The default
key is the module class name and is sufficient for a configuration-free module.
A configurable module must return a deterministic key that includes every option affecting its
installed JSON behavior. Do not include secrets, mutable process state, or unrelated values.
```java
public final class ConfiguredJsonModule implements ForyJsonModule {
private final boolean compactNames;
public ConfiguredJsonModule(boolean compactNames) {
this.compactNames = compactNames;
}
@Override
public String moduleKey() {
return getClass().getName() + ":compactNames=" + compactNames;
}
@Override
public void install(ModuleContext context) {
// Register the codecs, factories, or Mixins selected by this configuration.
}
}
```
For a Scala example that packages derived third-party enum codecs in a module, see
[Packaging Derived Codecs in a Module](scala.md#packaging-derived-codecs-in-a-module).