This release includes breaking changes for platform teams planning a safe upgrade.
✓ No known CVEs patched in this version
Topics
+12 more
Affected surfaces
Summary
AI summaryBroad release touches Build, Highlights, Internal, and Detailed release notes.
Full changelog
v1.6.7 — Dependency cleanup release
TL;DR — Zero breaking changes. Lighter runtime classpath
(Kotlin stdlib gone, flexmark narrowed to the 3 modules actually
used, jackson-yaml marked optional). Plus one latent bug fix in
DocumentSession.registry().register(...) cache invalidation.
Install
Maven Central (recommended):
<dependency>
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose</artifactId>
<version>1.6.7</version>
</dependency>
Gradle:
implementation("io.github.demchaav:graph-compose:1.6.7")
Highlights
- 🪶 Lighter runtime — Kotlin stdlib removed (the library is
Java-first; no production.ktsources existed),flexmark-all
aggregator replaced byflexmark+flexmark-util-ast+
flexmark-util-data(the three modulesMarkDownParseractually
uses),jackson-dataformat-yamlmarked<optional>true</optional>
(mirrors the existingpoi-ooxmlpattern), unused
jackson-module-jsonSchemaand the directsnakeyamldeclaration
dropped. - 🐛 Layout-cache fix —
session.registry().register(...)now
invalidates the layout cache the same way
session.registerNodeDefinition(...)does. Previously, registering
a definition throughregistry()silently left a stale compiled
layout in the cache. - ✅
japicmpverdict —semver PATCH, compatible bug fixvs
the v1.6.6 baseline. The one surface delta isNodeRegistry
becoming non-finalso the session can install an
auto-invalidating subclass.
Migration from v1.6.6
No code changes required for typical usage. Pure-PDF consumers
and JSON-only ConfigLoader callers carry on unchanged.
If you previously got these dependencies transitively through
GraphCompose, declare them explicitly:
| If you transitively depended on… | Add to your build |
|---|---|
| Kotlin stdlib | org.jetbrains.kotlin:kotlin-stdlib-jdk8 |
| Flexmark extensions (tables, footnotes, gfm-strikethrough, …) | the relevant com.vladsch.flexmark:flexmark-ext-* modules |
| YAML config loading through ConfigLoader | com.fasterxml.jackson.dataformat:jackson-dataformat-yaml |
| jackson-module-jsonSchema | com.fasterxml.jackson.module:jackson-module-jsonSchema |
| The commons-logging API beyond SLF4J routing | commons-logging:commons-logging (we exclude it from PDFBox and bridge via jcl-over-slf4j) |
Next
v1.6.8 is in develop — CV v2 migration completion (inline
markdown-link parser for project/education titles) plus polish
follow-ups from the v1.6.7 senior review. v1.7.0 is the
canonical-DSL feature minor (LineBuilder.dashed, inline shapes,
TimelineBuilder, dx shortcuts, recipes docs).
Resources
📦 Maven Central
· 📚 Javadocs
· 📋 Full CHANGELOG
· 🗺️ Roadmap
· 📐 API stability policy
Detailed release notes
v1.6.7 — 2026-06-01
Transitive dependency cleanup. v1.6.7 narrows the runtime
classpath GraphCompose imposes on consumers. The Kotlin standard
library is gone (the codebase is Java-first; no production
.kt sources exist), the flexmark-all aggregator is replaced
with the three modules MarkDownParser actually references,
jackson-dataformat-yaml is marked <optional>true</optional>
(mirroring the existing poi-ooxml pattern — only consumers that
load YAML configs through ConfigLoader need to pull it in),
jackson-module-jsonSchema and the explicit snakeyaml
declaration are dropped as unused, and jcl-over-slf4j is added
explicitly so PDFBox's commons-logging call sites keep routing
through SLF4J after the flexmark narrowing (the bridge was
previously provided transitively via flexmark-all). The cycle
also fixes a latent layout-cache staleness bug on
DocumentSession.registry().register(...) (Track I3): the
registry returned by registry() is now a session-owned wrapper
that invalidates the layout cache on every mutation, matching the
semantics of DocumentSession.registerNodeDefinition(...).
Zero breaking public API changes. The japicmp gate against
the v1.6.6 baseline reports semver PATCH, compatible bug fix —
the one surface delta is NodeRegistry becoming non-final so
DocumentSession can install the auto-invalidating subclass
described above. All existing call sites compile and run
unchanged. The transitive cleanup is a runtime-classpath change,
not a compile-surface change.
Migration from v1.6.6. Consumers that relied on dependencies
flowing transitively through GraphCompose must now declare them
explicitly:
| If you transitively depended on… | Add to your build |
|---|---|
| Kotlin stdlib via GraphCompose | org.jetbrains.kotlin:kotlin-stdlib-jdk8 |
| Flexmark extensions (tables, footnotes, gfm-strikethrough, …) | the relevant com.vladsch.flexmark:flexmark-ext-* modules |
| YAML config loading through ConfigLoader | com.fasterxml.jackson.dataformat:jackson-dataformat-yaml |
| jackson-module-jsonSchema | com.fasterxml.jackson.module:jackson-module-jsonSchema |
| The commons-logging API beyond SLF4J routing | declare commons-logging:commons-logging explicitly (GraphCompose intentionally excludes it from PDFBox and bridges via jcl-over-slf4j) |
No code changes are required for typical usage — pure-PDF
consumers and JSON-only ConfigLoader callers carry on as before.
The next minor with new canonical DSL primitives is v1.7.0
(see ROADMAP.md).
Build
- Dropped the
kotlin-stdlib-jdk8compile dependency, the
kotlin-testtest dependency, and thekotlin-maven-plugin
build extension. GraphCompose is Java-first; no production
Kotlin sources exist, and the runtime now no longer carries
the Kotlin standard library transitively. Consumers that
relied onkotlin-stdlibflowing through GraphCompose must
declare it explicitly. - Replaced the
flexmark-allaggregator dependency with the three
modules actually referenced byMarkDownParser:flexmark
(core parser + AST),flexmark-util-ast(Node / NodeVisitor /
VisitHandler), andflexmark-util-data(MutableDataSet). No
extension modules (tables, footnotes, gfm-strikethrough, etc.)
are used by GraphCompose. Consumers that relied on extensions
flowing through GraphCompose must depend on the relevant
flexmark-ext-*modules explicitly. - Added
jcl-over-slf4jas an explicit compile dependency. PDFBox
3.0.7'sPDDocument.<clinit>callsorg.apache.commons.logging. LogFactorydirectly; we exclude PDFBox's owncommons-logging
artifact to keep one logging facade, and the bridge routes those
calls through SLF4J. Previously the bridge was provided
transitively viaflexmark-all; making it explicit keeps the
classpath reproducible after the flexmark narrowing above. - Marked
jackson-dataformat-yamlas<optional>true</optional>,
mirroring the existingpoi-ooxmlpattern. The only consumer is
ConfigLoader.loadConfigWithEnv(...)when the caller passes a
.yaml/.ymlresource; library consumers that load JSON
configs (or skipConfigLoaderaltogether) no longer pull in the
~1.7 MB SnakeYAML transitive footprint. Applications that load
YAML configs through this helper must now declare
jackson-dataformat-yamlin their own build. - Removed the unused
jackson-module-jsonSchemadependency — no
code path references it. - Removed the explicit
snakeyamldependency declaration and the
snakeyaml.versionproperty. SnakeYAML is now resolved
transitively (andoptional) throughjackson-dataformat-yaml,
which version-aligns it with Jackson's BOM. - Bumped
net.sf.jasperreports:jasperreports6.21.3 → 7.0.7
in the benchmarks module. Benchmarks are a sibling Maven module
consumed only by the manual performance harness — no impact on
library consumers (#111).
Documentation
ConfigLoader.loadConfigWithEnvJavadoc now states the YAML
path requiresjackson-dataformat-yamlon the classpath and
throwsNoClassDefFoundErrorwhen the optional dep is absent.DocumentSession.registry()Javadoc now explains that the
returned registry is a session-owned wrapper whose
register(...)mutates the registry and invalidates the
layout cache, making the two registration entry points
(session.registry().register(...)and
session.registerNodeDefinition(...)) interchangeable.
Fixes
DocumentSession.registry().register(...)now invalidates the
layout cache the same way
DocumentSession.registerNodeDefinition(...)does. Previously,
registering a node definition throughregistry()mutated the
registry in place but left the cachedLayoutGraphpinned to
the previous compile, so a follow-up call torender(...)or
layoutGraph()silently returned the stale graph routed through
the old definition. Implemented by wrapping the session's
NodeRegistryin a private session-owned subclass that funnels
everyregister(...)call throughinvalidate(). (Track I3.)
Internal
NodeRegistryis no longerfinalsoDocumentSessioncan
install a session-owned subclass that auto-invalidates the
layout cache on mutation (see Fixes above). Standalone
NodeRegistryinstances retain their previous behaviour.- Replaced eight residual
org.jetbrains.annotations.NotNull/
@Nullableusages withlombok.NonNull(where the surrounding
file already used Lombok) or removed them entirely (private
methods and test fixtures).org.jetbrains:annotationsis no
longer on the runtime classpath after the Kotlin removal.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About GraphCompose 2.0
All releases →Related context
Related tools
Earlier breaking changes
- v2.0.0 Package rename: layered template packages dropped `.v2` suffix; update imports.
- v2.0.0 Removed dormant ECS engine internals (EntityManager, SystemECS, Entity components, render pipeline).
- v2.0.0 Removed linkOptions() accessor; use linkTarget() and ExternalLinkTarget.options().
- v2.0.0 Removed PDF‑typed document‑chrome overloads on DocumentSession; use backend‑neutral metadata/watermark/protect/header/footer.
- v2.0.0 Removed DSL name-aliases DocumentSession.builder() and DocumentDsl.text(); use builder() and paragraph().
Beta — feedback welcome: [email protected]