Skip to content

Latest commit

 

History

History
82 lines (55 loc) · 6.35 KB

CLAUDE.md

File metadata and controls

82 lines (55 loc) · 6.35 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Jackson modules-base is a multi-module Maven project containing 11 foundational Jackson 3 extension modules that build directly on jackson-databind. Each module is independent (no inter-module dependencies).

Modules: afterburner, blackbird, mrbean, guice, guice7, jaxb, jakarta-xmlbind, osgi, android-record, no-ctor-deser, spi-subtypes

(paranamer is not part of 3.x — it only appears commented out in the root pom.xml.)

There are also three test-only, never-published modules: afterburner-tests and blackbird-tests have no module-info.java, so their test POJOs live in the unnamed module, as in most applications (see each module's README.md). For Afterburner this covers the bytecode-generation paths it disables for beans in named JPMS modules; Blackbird's in-tree tests run inside Blackbird's own named module, and blackbird-tests also holds the tests that need the packaged jar or other JDKs; blackbird-jpms-tests is a foreign named module that requires blackbird and runs on the module path.

Blackbird builds only on JDK 25+: blackbird, blackbird-tests and blackbird-jpms-tests are in the root pom's blackbird-jdk25 profile (activated on JDK 25+). On an older JDK the full build silently leaves them out, and -pl blackbird fails with "Could not find the selected project in the reactor"; use a JDK 25 (JAVA_HOME=... ./mvnw ...) for Blackbird work.

Maven coordinates: groupId tools.jackson.module, parent tools.jackson:jackson-base; depends on tools.jackson.core:jackson-databind.

Build Commands

# Full build (all modules)
./mvnw -B -q -ff -ntp verify

# Build a single module
./mvnw -B -q -ff -ntp verify -pl afterburner

# Run tests only (all modules)
./mvnw -B -ff -ntp test

# Run tests for a single module
./mvnw -B -ff -ntp test -pl mrbean

# Blackbird modules need JDK 25+ (not in the reactor on older JDKs)
JAVA_HOME=/path/to/jdk25 ./mvnw -B -ff -ntp test -pl blackbird

# Run a single test class
./mvnw -B -ff -ntp test -pl afterburner -Dtest=TestSimpleSerialize

# Run a single test method
./mvnw -B -ff -ntp test -pl afterburner -Dtest=BasicDeserializeTest#testIntMethod

Java 17 is the minimum (javac.src.version 17); CI (main.yml) tests against 17, 21, 24, 25; Blackbird builds only in the 25 job, which also runs its runtime tests on 17 and 21 through -Dblackbird.test.oldJdks. The databind-push rebuild (dep_build_v3.yml) builds all other modules on 17 and 21 and only the Blackbird modules on 25, with the same old-JDK tests; keep the old-JDK wiring of the two workflows in sync. osgi and afterburner-tests add --add-opens java.base/java.lang=ALL-UNNAMED to their test argLine.

Architecture

Every module follows the same pattern:

  • A *Module class (e.g., AfterburnerModule, BlackbirdModule) extends Jackson's tools.jackson.databind.JacksonModule, registered on a mapper builder (e.g., JsonMapper.builder().addModule(...))
  • Package: tools.jackson.module.<name> (hyphens dropped or turned into sub-packages: androidrecord, noctordeser, spisubtypes, jakarta.xmlbind)
  • PackageVersion.java is generated from PackageVersion.java.in by the replacer Maven plugin — do not edit manually
  • JPMS module descriptors are real sources: <module>/src/main/java/module-info.java (and src/test/java/module-info.java for tests). Moditect is no longer used; the stray src/moditect/ dir in android-record is a leftover
  • SPI registration: src/main/resources/META-INF/services/tools.jackson.databind.JacksonModule (all modules except guice, guice7, osgi)

Key module categories

  • Performance (bytecode generation): afterburner (Byte Buddy-based), blackbird (generated per-bean codecs through the JDK ClassFile API; a multi-release jar that builds on JDK 25+ and is active only on 25+; on Java 17-24 module discovery skips it and explicit addModule throws IllegalStateException, see blackbird/README.md) — both disable themselves automatically in GraalVM native images via NativeImageUtil.isInNativeImage() check in setupModule
  • DI integration: guice (javax.inject), guice7 (jakarta.inject) — note: guice's ObjectMapperModule implements Guice's com.google.inject.Module, not Jackson's JacksonModule
  • Type materialization: mrbean (generates implementations for interfaces/abstract classes, Byte Buddy-based)
  • Annotation support: jaxb (javax.xml.bind), jakarta-xmlbind (jakarta.xml.bind)
  • Other: osgi (OSGi service injection), android-record (Android desugared records), no-ctor-deser (no default constructor), spi-subtypes (SPI-based subtype registration)

Dependencies

Unlike 2.x, nothing is shaded: afterburner and mrbean depend on net.bytebuddy:byte-buddy (version managed in the root pom as version.bytebuddy) as a regular dependency. ASM appears only as a test dependency.

Testing

  • Framework: JUnit 5 (Jupiter)
  • Base test classes: Each module has its own (e.g., AfterburnerTestBase, BlackbirdTestBase, BaseJaxbTest, BaseTest) providing mapper construction helpers and shared test types
  • Test location: <module>/src/test/java/tools/jackson/module/<name>/
  • Tests use static imports from org.junit.jupiter.api.Assertions
  • Mapper construction in tests: Use mapperBuilder() (returns JsonMapper.Builder with module pre-registered) or newObjectMapper() factory methods from the test base class; newVanillaJSONMapper() gives a baseline mapper without the module
  • Test helpers: q("str") wraps in double-quotes, a2q("{'a':1}") converts single to double quotes; assertion helpers verifyException(), assertToken()
  • SPI test: ModuleSPIMetadataTest verifies discovery via ServiceLoader.load(JacksonModule.class); present in afterburner, android-record, blackbird, jakarta-xmlbind, mrbean, no-ctor-deser, spi-subtypes (not yet in jaxb, which is registered)

Release & Branching

  • Main branches: 3.x (Jackson 3 development, default branch) and 2.x (head of the 2.x line); there is no master
  • Development branches: per-minor-version branches (e.g., 3.0, 3.1, 3.2; 2.21, 2.22); fixes merge forward (e.g., 2.21 → 2.22 → 2.x → 3.1 → 3.2 → 3.x)
  • Current version (this branch, 3.x): 3.3.0-SNAPSHOT
  • Releases use maven-release-plugin; snapshots deploy to Sonatype Central Portal