Netflix's ja preview makes Java's module descriptor the project contract

Netflix engineer Danny Thomas's module-first preview splits dependencies, formatting, symbol search and documentation into composable CLI tools.

By · Published

Primary source: Netflix TechBlog

Why it matters

ja tests whether Java can make dependencies, source navigation and access controls legible to coding agents without hiding the project model inside an IDE or build DSL.

A close-up view of a computer monitor displaying code and command-line output from a Java development tool.

Netflix JVM engineer Danny Thomas's ja preview gives Java developers and coding agents a command-line toolchain built around the language's module system instead of the class path.

Thomas, a Melbourne-based developer productivity engineer, has worked on Netflix's Java build ecosystem and JVM performance. He previously documented Netflix's adoption of generational ZGC, reporting in March 2024 that over half of its critical streaming-video services were running JDK 21 with the collector. His new project moves further up the development cycle, where dependencies, source code and documentation have to be found before an application ever reaches production.

In a Netflix TechBlog post, Thomas argues that Java's strong IDE experience left the language with fewer small command-line tools than coding agents now need. An IDE can quietly maintain a compiled project view, navigate declarations and organize imports. An agent operating through a terminal needs each of those capabilities exposed through predictable commands and machine-readable output.

Thomas's answer is to make module-info.java the source of truth for a project. ja records dependency versions beside standard requires directives and places metadata, including the application's main class, in documentation tags. The same descriptor can then drive development, compilation, testing, packaging and distribution.

Five tools, one project description

ja is an orchestration layer. Thomas divided the underlying work among four standalone tools that can also be used without adopting ja:

  • jig resolves module versions, compiles and assembles projects, and produces standard module-system arguments for javac, java, javadoc and jlink. It also connects the module model to Maven repositories.
  • jfmt formats modern Java, cleans up imports and normalizes qualified type names. It is built on google-java-format, with rules adapted for current Java syntax and OpenJDK practice.
  • jist searches classes, methods, fields and source files through a terminal-friendly interface. It can find exact symbols and semantic usages without requiring an IDE index.
  • jdocserver serves local, browsable API documentation for a JDK or a ja workspace, generating pages as they are requested.

Each tool implements Java's Tool or ToolProvider interfaces, which allows it to run inside a Java process. They are intended to sit inside a JDK beside familiar commands such as jdeps, jlink and jshell.

The architecture reflects a practical view of agent development. A coding agent does not need a second graphical development environment hidden behind an API. It needs narrowly scoped commands that return reliable output, preserve errors and compose with shell workflows. Thomas designed ja's output to stay concise so agents can retain the information that matters within their context limits.

Maven remains the foundation

Thomas is not asking Java developers to abandon Maven Central. jig uses Maven repositories for discovery and publishing, while ja changes how a project describes what it needs.

That bridge matters because Java's module system still has uneven coverage across published libraries. Netflix says a survey of the 1,000 most popular Maven Central artifacts found 232 with explicit module definitions and 248 with automatic module names. The remaining 520 expressed no module-name preference.

Thomas uses Maven's verified group namespaces to derive canonical module coordinates. Existing libraries can publish a relocation POM pointing from that coordinate to the artifact's established location. jig can also infer likely coordinates from common Maven naming conventions and carries aliases for popular modules that lack reverse-domain names.

That compatibility work is the part most likely to determine whether ja can graduate from an interesting design to a useful development system. Maven 4 already distinguishes class-path and module-path artifacts, while Gradle has years of investment in dependency management, build caching, plugins and multi-project builds. Thomas is offering a narrower proposition: Java's own module descriptor can become the durable contract shared by the compiler, packaging tools, developers and coding agents.

Netflix has a credible testing ground for that proposition. Netflix's JVM team says it supports about 3,000 Git repositories used by hundreds of engineers, producing roughly 9,000 JAR artifacts per day. The ja repository directs Netflix engineers to an internally bundled toolchain, indicating that Thomas is developing the public preview alongside a Netflix-specific distribution.

The integrity bet

The move away from the class path also serves Java's tightening access controls. Broad permissions granted to ALL-UNNAMED code can obscure which dependency needs reflective, native or final-field access. ja lets libraries declare those requirements as module metadata, while leaving the consuming application responsible for authorizing them.

Resolved binary dependencies are recorded with persistent hashes in a module-info.hash file. Later resolutions reject an artifact when its contents change. ja also treats annotation processing as an explicit code-generation step, placing generated source beside ordinary source so it can be inspected before assembly without running the generator again.

Those decisions make the module descriptor carry security and integrity information throughout a project's life. The bet is that explicit metadata will help human reviewers and coding agents understand the same boundaries, instead of reconstructing them from build scripts, command-line flags and IDE state.

Preview means preview

ja currently requires JDK 25 or later. The installer creates a ja-enabled copy of an existing JDK rather than modifying the source installation, and Netflix provides scripts for macOS, Linux and Windows. The tools are licensed under Apache 2.0, with standalone artifacts for several components available through Maven Central.

The release is moving quickly. GitHub lists v0.21.5 as the latest release on September 18th, following several version tags published across September 17th and 18th. DanielThomas is listed as a contributor on multiple releases in that sequence, including changes to installation, automatic module publishing and the bundled version of jist.

That cadence fits an early preview, where interfaces and installation details remain in motion. ja still has to prove that module-first projects can absorb the irregularities of existing Java libraries without pushing complexity back onto developers. It also has to coexist with established Maven and Gradle builds that companies have spent years tuning.

Thomas has chosen a sensible place to start. Coding agents expose every assumption that an IDE once handled quietly. By turning those assumptions into small commands and explicit module metadata, ja gives Java a development interface that both humans and agents can inspect. The next test is whether Java developers decide that the module descriptor should carry that much responsibility.

Reader comments

Conversation for this story loads after sign-in.