Skip to content

docs: the Java and Kotlin bindings have no documentation surface #628

Description

@raeq

Summary

The JVM binding shipped in 0.13.0 (#540, closing #43) and publishes two artifacts to
Maven Central — dev.disarm:disarm and dev.disarm:disarm-kotlin. The documentation
site never absorbed it. Python, Rust, Ruby and Node each have a docs/<lang>/ directory
and a nav entry; the JVM has neither, and a reader who arrives from Maven Central has no
supported path from the artifact to a working example.

This is the failure mode #50 was written to prevent. That issue closed on the premise that
the language-neutral scaffold was in place so "every subsequent binding plugs straight into
it instead of bolting on a Python-shaped page." Node plugged in. The JVM binding, merged
later, did not.

What the survey found

No JVM pages exist.

Surface Getting started API reference
Python docs/python/getting-started.md (58 lines) docs/api/*.md (11 pages)
Rust docs/rust/getting-started.md (140 lines) docs/RUST_API.md
Ruby docs/ruby/getting-started.md (70 lines) docs/ruby/api.md (598 lines)
Node docs/node/getting-started.md (79 lines) docs/node/api.md (544 lines)
Java / Kotlin

mkdocs.yml lists four languages under Getting started and four under API Reference.
Neither list includes the JVM.

No JVM code appears anywhere in docs/. Fenced blocks across the whole tree:
307 python, 83 ruby, 75 ts, 70 rust, 44 bash — and zero java, zero kotlin.
Tabbed per-language examples: 52 Python, 50 Rust, 40 Ruby, 39 Node, 0 Java, 0 Kotlin.
Pages such as graphemes.md and
filenames.md already carry four tabs each, so the JVM is
the only published binding a reader cannot see an example of.

Four lines in the entire docs tree mention the binding. (Discounting the many
"Javanese" matches, and the Trojan Source paragraph at
limitations.md:243, which is about the Java language.)

The undocumented surface is large. Disarm.java
exposes 66 public static methods across roughly 50 distinct names;
Disarm.kt exposes
51 functions. Twenty public types sit alongside them — AnomalyReport, Finding,
HostnameAnalysis, LangMeta, ScriptMeta, Lexicon, Pipeline, DigitPolicy,
NormalizationForm, TargetScript, Platform, UnmappedConfusable, Untranslatable,
AutoLangInspection, the four options builders, and the two exception classes. None of it
is described outside the source.

The JVM-specific parts, which no other page can stand in for

Concept pages transfer between languages. These do not, and they are exactly what a JVM
reader needs:

  • Pipeline and Lexicon are AutoCloseable over native handles
    (Pipeline.java:19,
    Lexicon.java:20).
    A Cleaner backstops a forgotten close(), but try-with-resources is the intended
    idiom and appears in no published example. Python, Ruby and Node callers face nothing
    equivalent, so no existing page teaches it.
  • Install coordinates. dev.disarm:disarm:0.13.0, dev.disarm:disarm-kotlin:0.13.0,
    Maven Central via the Sonatype Central Portal. Recorded only in build.gradle.kts and
    bindings/java/PUBLISHING.md, which is a maintainer runbook.
  • JDK floor is 21 (JavaLanguageVersion.of(21), jvmToolchain(21)). Only in the
    build files. Node's page states "Node 14+" in its second paragraph.
  • Five bundled native targetsdarwin-aarch64, darwin-x86_64, linux-x86_64,
    linux-aarch64, windows-x86_64 — appear only in the publish-java.yml matrix.
    Someone on musl or 32-bit ARM has to read CI YAML to discover they are unsupported.
    Node's page lists its platforms; Java's does not exist.
  • The exception hierarchy. DisarmInvalidArgumentException extends DisarmException,
    the JVM counterpart to the DisarmError / DisarmInvalidArgument pair that
    node/getting-started.md devotes a section to.
  • The two call styles. Java uses static methods with options builders
    (TransliterateOptions, SlugOptions, SanitizeFilenameOptions, MlNormalizeOptions);
    Kotlin uses String extensions with default arguments. A reader choosing an artifact
    cannot see the difference anywhere.
  • The @JvmOverloads signature guarantee (Kotlin String.normalizeConfusables lost its 2-arg JVM signature in #574 (no @JvmOverloads) #588) is written up in BINDINGS.md, which
    is contributor-facing. JVM consumers are the ones whose compiled call sites the
    guarantee protects, and they have no user-facing statement of it.

Entry points route readers away

  • README.md contains no occurrence of "Java", "Kotlin", "JVM", "Maven" or "Gradle". Its
    tagline reads "bindings for Python, Ruby, and more" and its Get started in your
    language
    line offers Python · Rust · Ruby. Node is missing from it too.
  • index.md:12 and _index_nav.md:8 repeat the
    same three-language list.
  • The published POM sets url to the repository root
    (build.gradle.kts:152), so a visitor
    arriving from Maven Central lands on a README that never names their language.
  • bindings/java/ has no README.md. bindings/node/ and bindings/ruby/ both do.

Two stale or wrong statements

  1. BINDINGS.md still carries Java as a planned binding. The artifact table lists the
    crate, wheel, gem and npm package with no Maven coordinates, and the per-language
    conventions table shows Java Add Java bindings for translit-core (Maven Central) #43 with "JNI or Panama (FFM)" as an open choice —
    though Add Java bindings for translit-core (Maven Central) #43 is closed and the binding shipped on a safer-ffi C ABI with JNI. Kotlin has
    no row at all despite being a separately versioned artifact.
  2. The one sentence that does mention Java gets Ruby wrong. Both
    which-function.md:46 and
    adversarial-defense.md:245 read
    "analyzeHostname in Node/Ruby/Java", but the Ruby method is analyze_hostname
    (disarm.rb:183,
    ruby/api.md:202).

Why it stayed invisible

docs.yml is path-filtered on docs/**, mkdocs.yml, python/disarm/**,
requirements/docs.txt and itself. Nothing under bindings/ triggers a docs build, so no
change to the JVM API can turn a docs check red. mkdocs build --strict catches broken
links and missing nav pages; it cannot catch a binding that was never given a page.

Proposed scope

  1. docs/java/getting-started.md and docs/java/api.md, mirroring the Node and Ruby
    pair. Cover install coordinates for both Gradle and Maven, the JDK 21 floor, the five
    bundled targets, the exception hierarchy, the builder options, try-with-resources for
    Pipeline and Lexicon, and the Java-versus-Kotlin call styles.
  2. Nav entries in mkdocs.yml under Getting started and API Reference. Add java and
    kotlin to theme.hljs_languages while there.
  3. Java and Kotlin tabs on the user-guide pages that already carry four.
  4. Correct the language lists in README.md, docs/index.md and docs/_index_nav.md,
    adding Node as well as the JVM.
  5. Refresh both BINDINGS.md tables: Maven coordinates in the artifact table, Java marked
    shipped with its real native tech, a Kotlin row added.
  6. Fix the analyze_hostname naming error in the two pages that carry it.
  7. Add bindings/java/README.md so the GitHub directory view and any future POM
    url pointing at it describe the artifact.

Items 4 and 6 are small and independent of the rest; they can land ahead of the new pages.

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Projects

Status
Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions