Skip to content

Documenter: canvas generation fails when extracted Javadoc contains quotes or unbalanced braces (BasicJsonParser) #1762

Description

@gnycholas

Setup: Spring Modulith 2.0.6, Spring Boot 4.0.6, Java 21.

spring-modulith-apt extracts Javadoc into target/generated-spring-modulith/javadoc.json, and Documenter.writeDocumentation() parses that file with org.springframework.boot.json.BasicJsonParser (via the Asciidoctor static initializer → SpringModulithDocumentationSource). BasicJsonParser is explicitly documented as not fully JSON-compliant, and real-world Javadoc easily produces valid JSON it cannot parse — which makes canvas generation fail for the whole project:

java.lang.ExceptionInInitializerError
	at org.springframework.modulith.docs.Asciidoctor.getSpringModulithDocsSource(Asciidoctor.java:431)
	at org.springframework.modulith.docs.Asciidoctor.<clinit>(Asciidoctor.java:59)
	at org.springframework.modulith.docs.Documenter.toModuleCanvas(Documenter.java:434)
	...
Caused by: org.springframework.boot.json.JsonParseException: Cannot parse JSON
	at org.springframework.boot.json.BasicJsonParser.parseList(BasicJsonParser.java:53)
	at org.springframework.modulith.docs.SpringModulithDocumentationSource.from(SpringModulithDocumentationSource.java:137)

Minimal reproductions

Both inputs are valid JSON (they parse fine with Jackson / JSON.parse / Python json), and both fail with IllegalStateException: Expecting double-quotes around field names:

BasicJsonParser parser = new BasicJsonParser();

// 1. escaped double quote followed (later) by a comma inside a string value
parser.parseList("[{\"name\":\"x\",\"comment\":\"\\\",.\",\"methods\":[]}]");

// 2. unbalanced curly brace inside a string value, with a subsequent entry
parser.parseList("[{\"k\":\"abre { e nao fecha\"},{\"k\":\"x\"}]");

Real-world Javadoc that triggers each case:

  1. Quoting a UI message: ... shows the message \"if the e-mail exists, we sent a link\", avoiding enumeration. — the escaped quote plus the comma inside the quoted fragment mis-splits the map entries.
  2. Any prose containing a lone { (or }) — e.g. mentioning literal braces or half-open interval notation combined with braces — breaks the parser's depth tracking across array entries.

In our codebase (~640 documented types), dozens of legitimate Javadoc comments contain double quotes or brace/bracket characters, so writeDocumentation() is effectively unusable without pre-processing.

Suggestion

Parse the APT output with a compliant parser — e.g. Jackson when it is on the classpath (it already is for many Modulith users via spring-modulith-events-jackson) — or escape/normalize on the APT side when writing javadoc.json.

Workaround

We currently re-serialize target/generated-spring-modulith/javadoc.json before invoking the Documenter, replacing ", {, }, [, ] inside comment values — cosmetic in the canvas, but it lets BasicJsonParser through.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions