Build with dependencies and CI ============================== Once :doc:`getting-started` works for a source root, give extraction the same source and dependency inputs your Java compiler needs. The extension does not invoke Maven or Gradle, run annotation processors, or resolve dependencies for you. Prepare those inputs before running Sphinx. Choose where extraction runs ---------------------------- * **During Sphinx:** set ``java_sources`` and ``java_classpath`` in ``conf.py``. This is the simplest path when JDK 25 is available on the documentation builder. * **Before Sphinx:** run ``sphinx-java-autodoc`` in the Java build job, then pass its XML to Sphinx with ``java_model``. The Sphinx job needs no JDK. For example, for a locally available dependency: .. code-block:: python java_sources = ["../src/main/java"] java_classpath = ["../lib/dependency.jar", "../other-module/target/classes"] java_generate = "api" Dependencies, generated sources and multiple modules ---------------------------------------------------- Pass dependency JARs or class directories through ``java_classpath`` (a list), ``--classpath`` (platform path separator), or ``--classpath-file``. Wildcard classpath expansion is not supported: enumerate files explicitly. Dependencies are never downloaded implicitly. A missing dependency results in compiler diagnostics with the failing symbol and a classpath hint. List several source roots to combine non-JPMS Maven/Gradle modules: .. code-block:: python java_sources = [ '../core/src/main/java', '../client/src/main/java', '../client/target/generated-sources/annotations', ] java_classpath = ['../lib/dependency.jar'] Produce generated sources before running Sphinx. No annotation processors execute inside extraction; Lombok-like compiler AST transformations are not supported. Do not include test sources unless they are part of the API you intend to publish. JPMS ``module-info.java`` inputs are rejected with an actionable error in this release; use non-modular roots or explicitly enumerate declaration files. Cross-module JPMS identity, module paths and split packages are deferred. A binary dependency is enough to resolve a reference or signature. To inherit its Javadoc, set ``java_sourcepath`` to directories containing dependency sources: .. code-block:: python java_sources = ["../src/main/java"] java_sourcepath = ["../dependency-sources"] These directories supply compiler lookup and ancestor comments, but are not selected for API pages. The CLI accepts repeated ``--sourcepath DIRECTORY`` arguments. Lookup source contents and order participate in cache invalidation; changing an ancestor comment refreshes the consuming documentation. Published source roots take precedence over lookup-only roots. Supply non-JPMS directories. Explicit extraction and rendering --------------------------------- Use this when Java extraction runs in a separate job from Sphinx. From your project root, with JDK 25 available: .. code-block:: console sphinx-java-autodoc src/main/java --release 17 --warnings-as-errors \ --cache build/java-cache -o build/api.xml Add ``--classpath-file build/classpath.txt`` when dependencies are needed. ``--encoding`` and repeated ``--exclude-package`` arguments match the ``java_encoding`` and ``java_exclude_packages`` settings. CLI paths are relative to the working directory. Then configure ``docs/conf.py``: .. code-block:: python extensions = ['sphinx_java_autodoc'] java_model = '../build/api.xml' java_generate = 'api' Do not also set ``java_sources``. Reading an existing model requires no JDK. The build pipeline must rerun extraction when sources or dependencies change; Sphinx can only detect changes in the supplied model. The extraction command preserves the last successful output if compilation or strict diagnostics fail. Maven ----- The Maven and Gradle fixtures resolve Commons Lang and generate ``demo.BuildInfo`` before compilation. Both complete workflows have been executed; see :doc:`compatibility` for versions. Dependency resolution is an explicit build step. ``examples/maven/pom.xml`` reuses the standalone source fixture. Resolve build plugins and dependencies in an explicit preparation step. The extension itself never invokes Maven:: mvn -f examples/maven/pom.xml -DskipTests compile \ org.apache.maven.plugins:maven-dependency-plugin:3.11.0:build-classpath \ -Dmdep.includeScope=compile -Dmdep.outputFile=target/classpath.txt sphinx-java-autodoc examples/standalone/src examples/build-consumer/src \ examples/maven/target/generated-sources/java-autodoc \ --classpath-file examples/maven/target/classpath.txt \ -o build/maven-api.xml --cache build/java-cache --warnings-as-errors For your own project, replace the fixture root with ``src/main/java``. If no external dependencies exist, omit ``--classpath-file``. The `Maven dependency plugin `_ writes platform-separated classpaths, including provided dependencies when compile scope is selected. Compile/generate-sources are explicit project build steps and may run project build plugins; extraction does not execute application code. Gradle ------ ``examples/gradle/build.gradle`` reuses the same sources and provides an explicit ``writeJavaAutodocClasspath`` task. With a Gradle distribution supporting JDK 25:: gradle -p examples/gradle classes writeJavaAutodocClasspath sphinx-java-autodoc examples/standalone/src examples/build-consumer/src \ examples/gradle/build/generated/sources/java-autodoc \ --classpath-file examples/gradle/build/java-autodoc-classpath.txt \ -o build/gradle-api.xml --cache build/java-cache --warnings-as-errors For your project, the `Java plugin `_ provides ``sourceSets.main.compileClasspath``. Write its ``asPath`` to a UTF-8 file; pass source directories separately. No Gradle wrapper or automatic distribution download is bundled here. To verify both complete examples, including extraction and strict rendering with Java unavailable on PATH, run:: uv run --locked python tests/build_tools_check.py Pass ``--maven`` and ``--gradle`` with executable paths when needed. The same check runs in the required CI consumer job. These fixtures use an explicit template-copy step for generated sources; they do not demonstrate annotation processing. Publish the site from CI ------------------------ This GitHub Actions workflow builds strictly on every push to ``main`` and deploys to GitHub Pages. In the repository settings, set **Pages → Source** to **GitHub Actions**. Save it as ``.github/workflows/docs.yml``: .. code-block:: yaml name: Documentation on: push: branches: [main] permissions: contents: read jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/setup-java@v6 with: distribution: temurin java-version: "25" - uses: actions/setup-python@v7 with: python-version: "3.12" - run: python -m pip install sphinx-java-autodoc # Prepare java_classpath inputs and generated sources here, for example # with the Maven or Gradle commands below. - run: sphinx-build -W --keep-going -n docs docs/_build/html - uses: actions/upload-pages-artifact@v5 with: path: docs/_build/html deploy: needs: build runs-on: ubuntu-latest permissions: pages: write id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pages@v5 Each run starts from a clean output directory, so removed types do not leave old pages behind. Install the extension from your own lockfile or requirements file if you have one, and pin actions to commit SHAs if your project does. This repository publishes its own site with the same JDK setup, strict build and Pages actions; this standalone workflow has been checked with ``actionlint`` but has not run in another repository. Caching and parallelism ----------------------- The Sphinx cache lives under ``/java-cache``. The CLI defaults to ``.java-autodoc-cache`` or accepts ``--cache``. Fingerprints include source paths and contents, classpath order and contents, source release, tool identity/JDK modules, extension version and extractor code. Cache hits still hash inputs; this costs I/O but catches edits even when timestamps are preserved. A changed input triggers whole-project extraction and re-reading of all Sphinx documents, including pages containing only Java roles and directives for types that were previously missing. Output contains no build timestamps or machine-specific source paths. Temporary work directories and atomic replacement protect simultaneous extraction into one cache. Sphinx ``-j 2`` reading/writing and domain inventory merges are tested. Separate Sphinx processes must use separate source/output generation directories; sharing one generated-page directory across independent builds is not supported. Generated skeletons are written only when changed. The ownership manifest records old and intended content hashes before page updates, so an interrupted generation can retry even if the Java model changes again. Edited pages still stop the build. Removed types leave the source toctree and inventory; Sphinx can retain old HTML files in an existing output directory, so publish from a clean output directory. After extracting, Sphinx deletes older models from ``/java-cache``. The CLI never evicts entries from its ``--cache`` directory; remove old ones when no extraction is using it. Direct doclet invocation ------------------------ For direct doclet invocation, locate and compile the bundled source:: python -c "from sphinx_java_autodoc.extractor import DOCLET; print(DOCLET)" javac -proc:none -encoding UTF-8 -d build/doclet /printed/path/SphinxDoclet.java javadoc -quiet -encoding UTF-8 -protected \ -doclet sphinxjava.SphinxDoclet -docletpath build/doclet \ --sphinx-output build/api.xml -sourcepath src/main/java \ -classpath lib/dependency.jar com.example The doclet's ``--sphinx-exclude`` option takes excluded packages separated by commas. Prefer the Python CLI for content caching, atomic output and warning handling. The direct command takes ordinary Javadoc package or file inputs and does not provide the Python wrapper's cache or publication safeguards.