Introducing composable, module system native and agent pleasant command line instruments for contemporary Java improvement
By Danny Thomas, JVM Ecosystem Workforce

Current work on the Java language to pave the on-ramp has made it simpler than ever to start out a Java program and evolve it utilizing the complete language and platform. On the finish of that on-ramp lies Java’s mature construct and dependency administration ecosystem, able to carrying software program to huge scale and complexity.
That ecosystem reached its maturity by creating robust fashions for tasks, dependencies, and builds. When the Java Module System arrived, these fashions had been already serving builders exceptionally properly. The module descriptor consequently grew to become simply one other description of the challenge to maintain in settlement.
We’re excited to announce a preview of ja and its household of composable instruments, that construct on the capabilities of the Java Module System to offer a contemporary command line improvement expertise for Java. We take the module descriptor and make it an entire description of a challenge, with dependency variations sitting naturally beside its requires directives and module metadata offered by means of documentation tags:
/**
* @mainClass com.instance.software.Foremost
*/
module com.instance.software {
requires com.instance.framework; // @1.2.3
}
Mixed with command line ergonomics you’re used to in different languages, creating and consuming Java modules has by no means been simpler.
Composable Instruments
Java builders have lengthy been exceptionally properly served by graphical instruments. An IDE codecs supply, navigates between declarations and usages, presents API documentation, and maintains a compiled view of the challenge. That have has been so full that Java has had much less want to show the identical capabilities by means of small, composable command line instruments. These gaps turn into rapidly obvious when coding brokers work with the Java language, with brokers often struggling to find dependencies, documentation and sources.
ja solely supplies command line ergonomics and power orchestration, every function is underpinned by a standalone device. You don’t must undertake ja to get the good thing about these instruments, you may compose them in any manner you select:
- jig performs module model decision, compilation and meeting, outputting customary module system arguments to be used with different instruments. Additionally it is the bridge to and from Maven repositories offering a standalone module proxy and publishing instructions
- jfmt codecs supply utilizing the Code Conventions for the Java Programming Language, tailored for the trendy Java language. Avoids the quite common whitespace, indentation, import ordering and certified class references launched in agent written code
- jist supplies supply conscious image search, offering a grep model interface for understanding class information and their related sources. Offers coding brokers entry to symbols and sources with out indexing, LSPs or MCPs whereas interoperating with different construct instruments through an argument file contract
- jdocserver serves domestically browsable API documentation
These tasks use the device discovery and execution capabilities of the platform, and are meant to be put in in your JDK together with the usual instruments. All of them implement Software or ToolProvider, permitting them to be run in course of.
That is additionally the device discovery and execution mannequin for ja. There we use OptionChecker and non-obligatory customized metadata to find which module system choices are supported so it may well resolve the arguments on behalf of the device. This supplies a seamless transition out of your supply path modules to the usual JDK tooling resembling jdeps, jlink and jshell.
Maven as a basis
In a current survey of the 1,000 hottest artifacts on Maven Central, simply 232 had express module definitions and one other 248 declared automated module names. The remaining 520 expressed no Java module title opinion. The module system additionally makes no distinction between namespace and module title, so module-first tooling requires an answer to module naming and placement in current repositories.
Thankfully, Maven Central already provides printed artifacts a verified namespace. Publishers show management of reverse area group IDs, reflecting Sonatype’s lengthy standing case for namespaces in public repositories.
We use these conventions to ascertain a canonical Maven module coordinate, paring a verifiable DNS namespace with the whole module title, for instance pkg:maven/com.netflix/com.netflix.instruments.ja. For current modules, authors select to publish a single Maven relocation pom on the canonical coordinate, to permit for discovery of the unique coordinate.
When neither can be found, candidates are walked from the basis of the namespace utilizing frequent Maven artifact conventions inferring coordinates from module names. We additionally bundle a brief checklist of aliases for the preferred modules that don’t use a reverse DNS module title, however we propose authors ought to all the time namespace their modules. The module proxy in jig presents resolved modules utilizing the filename primarily based conventions for module naming, making even automated modules with out secure names secure when used with these instruments.
These conventions and placement methods enable the vast majority of current artifacts to be found utilizing solely the module title and model.
Integrity by default
ALL-UNNAMED has turn into sadly frequent in Java entry choices, due to the heavy use of the category path. It hides the supply of the technical debt that functions are incurring by permitting such entry and turns into more and more consequential as Java strikes towards Integrity by Default. For instance, Getting ready to Make Closing Imply Closing asks functions to explicitly authorize the modules allowed to mutate last fields.
We enable runtime entry necessities to bedeclared as module metadata and carried with the module descriptor all through the module’s lifecycle. For instance a library could document the entry it requires:
/**
* @enableFinalFieldMutation com.instance.framework
*/
module com.instance.framework {
}
Nonetheless, the consuming software stays in management and should explicitly authorize the framework, for it to be obtainable at runtime:
/**
* @mainClass com.instance.software.Foremost
* @enableFinalFieldMutation com.instance.framework
*/
module com.instance.software {
requires com.instance.framework; // @1.2.3
}
The command line interface for ja permits the dependency and authorization to be added collectively:
ja require com.instance.framework@1.2.3
--enable-final-field-mutation com.instance.framework
With out that authorization, dependency decision fails with an unhappy entry requirement. Native entry follows the identical mannequin by means of @enableNativeAccess and certified exports and opens are additionally supported.
Module integrity is ensured by persistent hashes of resolved binary dependencies in a module-info.hash file, sequent decision verifies these hashes and rejects an artifact that has modified.
We additionally take a step additional than the current enhancements to annotation processor safety by treating annotation processing as an express code era step. The ensuing sources are alongside common module supply, making them seen in code assessment and permitting a module to be assembled with out executing generator code.
Make modules your default
We predict each Java challenge must be modular, whatever the construct device you’re utilizing. In the event you’re a library creator producing automated modules, we’d encourage you to keep away from break up packages and produce express modules.
You will get began with our instruments at the moment with our set up information.
Go away the Class Path within the Rearview Mirror was initially printed in Netflix TechBlog on Medium, the place individuals are persevering with the dialog by highlighting and responding to this story.