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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions