This release makes bld resolve and transfer dependencies in parallel, adds
bill of materials support, and lets AI agents drive a build through the Model
Context Protocol. It also drops the retired Sonatype OSSRH repositories and
changes a handful of API signatures in ways that break binary compatibility
for already compiled callers, which together are what make this a major
version.
Dependency resolution and transfers
- Artifact transfers now run in parallel, with live progress in an interactive terminal and a single stable line per finished transfer in CI logs, pipes and IDE consoles. The number of parallel transfers is set with the
bld.transferParallelismproperty and defaults to 6,1makes them sequential again. - Transitive dependency resolution runs in parallel with speculative POM prefetching, through the new
ParallelDependencyResolverandPomPrefetcher. The number of parallel POM retrievals is set with thebld.resolutionParallelismproperty and defaults to 6,1disables the speculative retrieval. updatesand the resolution of wrapper extensions are parallelized as well.- The
downloadcommand and the wrapper extension resolver announce the analysis before it starts, with anAnalyzing dependencies...line and a separate one for the bld extensions, so a long resolution doesn't look like a pause. - The
downloadcommand batches the artifact transfers of all its scopes into a singleDependencyTransferBatch, so that one pass fills the wholelibdirectory instead of one pass per scope. - Transient retrieval failures are retried and the artifact retrieval connections are bounded by connect and read timeouts. A repository that fails transiently, or that serves a POM that doesn't parse, falls through to the next repository instead of failing the resolution.
- Added the
GOOGLE_MAVEN_CENTRAL,GOOGLE_MAVEN_CENTRAL_EUandGOOGLE_MAVEN_CENTRAL_ASIArepository mirrors. - Added
dependencyClasspathJarsandextensionClasspathJarstoBaseProject, which return the jars of a single dependency together with its transitive compile and runtime dependencies. The resolved classpaths are cached in thebldcache and come from the actual artifact transfers, so that a custom command can build an isolated classpath without resolving anything a second time once the cache holds them. - Local dependencies and local modules can be specified with an absolute path, and
localandlocalModuleaccept aFileor aPathnext to aString. - Added
DependencySet.include(DependencySet)to include a whole set at once, which carries the local dependencies, the local modules and the BOMs along with the dependencies. The copy constructor goes through it, where it used to copy the dependencies alone.
Bill of materials
- Added bill of materials support through
Bomand thebom(...)methods. A dependency that is declared without a version takes its version from a BOM, and a transitive dependency that matches a BOM entry is pinned to it. Abld.overrideproperty always wins, followed by a version that is explicitly declared in the build file, followed by a BOM. A dependency that is declared without a version and that neither an override nor an applicable BOM covers still resolves to its latest version. - BOMs apply across scopes the way classpaths do, a scope-local BOM takes precedence over an inherited one, and inherited BOMs follow the standard scope order.
- For the scopes that a BOM applies to, the
downloadcommand reports the version-less dependencies that neither those BOMs nor an override cover, and warns when a declared version differs from the version an applicable BOM supplies, or when two BOMs supply conflicting versions for the same dependency. - Published POMs carry a
dependencyManagementsection with the BOMs declared in the scopes that get published, which are compile, runtime and provided. A BOM declared for test or standalone stays out of the POM.
AI agents
- Added experimental MCP support through the new
mcpcommand, which serves the build commands of a project as Model Context Protocol tools over the stdio transport. Themcpcommand itself is never served, and a build can exclude others. Invoking a tool runs the command as a separate build process, with its console output captured separately from the protocol streams. - Tool results carry structured content with execution metadata, and the console output of a running command is streamed as log message notifications instead of arriving in one block when the command ends.
- The project layout, the declared dependencies and the transitive dependency tree are served as MCP resources.
./bld mcp installregisters the project with an MCP client by writing the configuration file inside the project directory:.mcp.jsonfor Claude Code and compatible clients,.cursor/mcp.jsonfor Cursor and.vscode/mcp.jsonfor VS Code. The server entry is merged into an existing configuration file rather than replacing it, so the other servers in that file stay, and--printprints the configuration instead of writing it.- The
publishcommand is flagged as needing explicit human confirmation and marked destructive in its tool annotations. That is advisory metadata for the client, the server doesn't block the call itself.requireConfirmation,excludeCommand,toolCallTimeoutandoutputLimitconfigure that side of the server. - Added the
--use-stderroption, which redirects the standard output of the wrapper and of the build to standard error, so that standard output stays free for the protocol while the build starts up.
Command line
- Added the
--verboseoption, with-vas its short form, which closes #67. - Added the
--auto-download-purgeoption, which turns on the behavior of theautoDownloadPurgeproject option for a single invocation. - Fixed #95: the help welcome message displays the Java version and vendor that
bldis running on. - Added
BuildExecutor.verbose,BuildExecutor.showStacktrace,BuildExecutor.offlineandAbstractOperation.verbosesetters, so that the verbose, stacktrace and offline state can also be set from build logic. - Added
BuildExecutor.resolveCommand, which exposes the command matching of the command line, including its unique prefix and fuzzy matches.
Operations
- Added the
instrumentcommand andInstrumentOperation, which applies RIFE2's bytecode transformations ahead of time as an alternative to the java agent. Ahead-of-time instrumented classes make continuations, meta-data merging and lazy loading work inside a GraalVM native image. JavacOptionsgained-Xlintoptions,--add-exports,--add-reads,--patch-module,--default-module-for-created-files,--sourceand--target, and the path list options now accept varargs and collections ofString,FileandPath. Null and empty values are consistently filtered out instead of ending up on the command line.- Fixed
JavacOptions.containsRelease, which checked for-releaseinstead of--release. classpathandmodulePathon the process operations acceptFilevarargs and collections.- Fixed #66: compiling reports when no source files are found.
- Fixed #69: running reports when no main class or module is specified.
Wrapper
- The wrapper retries transient download failures instead of failing the build on the first one.
- The wrapper jar contains the nested wrapper types and the RIFE2/core
Productclass, so that its user agent is formatted the same way the rest ofbldformats it. - The RIFE2 agent jar is located by its resolved name, which is what a snapshot version needs.
Publishing
- Repository names that a build file passes to
PublishOperation.repositoryare resolved when the publication runs instead of when the build file is constructed, so that resolving them doesn't affect every other command. - A repository name that isn't declared is reported as a warning and skipped, instead of becoming a repository at that relative path. A
bld.repo.property whose value isn't a location is refused outright. publish-localno longer reaches the repositories that a build file names, it publishes to the local Maven repository only.- Added
PublishOperation.clearRepositories, which clears both the repositories that were given as instances and the names that are still to be resolved. - Added
PublishOperation.dependencyRepositories, so that the repositories that resolve versions during publication can be set separately. - Dependencies that are declared without a version are frozen to a concrete version in the published POM, so that the POM is always complete. One that a BOM covers stays version-less and takes its version from the dependency management section, unless the flattened dependency management would supply a different version than the BOMs that apply to its scope, or a
bld.overridesupplies it, since the POM can reflect neither.
Project and CI
- Added a release train that releases
bld, RIFE2, RIFE2/core and the extensions together, described in RELEASE-TRAIN.md, together with a rehearsal sandbox that runs the whole thing against local repositories and remotes. - Added a workflow for publishing snapshot builds between releases, run by hand when one is wanted.
- The CI workflow was reworked into a modular design that configures databases, images and credentials through the matrix, with dependency caching and the bld JUnit reporter.
- Added CONTRIBUTING.md and an
llms.txtfile for discovery.
Other
- The
bldcache is stored as UTF-8. The cached dependency trees contain box drawing characters that the platform charset can't encode on every JVM. bldruns on Java 17 and later, and is tested on Java 17, 21, 25 and 26.- Updated to latest dependencies. The project blueprints moved to JUnit 6.1.3, RIFE2 1.10.0, Jetty 12.1.12 and jsoup 1.23.2.
Compatibility notes
- Several
JavacOptionsmethods changed signature without keeping the old ones:addModulesandmodulePathtake aCollectionwhere they took aList, andmoduleSourcePath,processorPathand their siblings take varargs where they took a singleFile,PathorString. Calls in source keep compiling, but an extension compiled against 2.3.0 that calls one of the affected signatures needs rebuilding to avoid aNoSuchMethodError. - The retired Sonatype OSSRH repositories were removed.
SONATYPE_RELEASES,SONATYPE_RELEASES_LEGACY,SONATYPE_SNAPSHOTSandSONATYPE_SNAPSHOTS_LEGACYno longer exist, as constants or as repository names. UseCENTRAL_SNAPSHOTSfor snapshots and publish releases through the Central Portal. - The project blueprints declare
CENTRAL_SNAPSHOTSwhere they used to declareSONATYPE_SNAPSHOTS, so a newly created project points at Central snapshots. - Artifact transfers happen in parallel, so the order of the download lines is no longer the order the dependencies are declared in, and an interactive terminal gets a live updating block instead of a line per transfer. Set
bld.transferParallelism=1to transfer them one at a time again, which restores the order but not the old output. - Published POMs changed. A dependency that is declared without a version now carries a concrete version unless a published BOM import supplies it, and a project that declares BOMs in the compile, runtime or provided scopes now emits a
dependencyManagementsection. publish-localno longer publishes to the repositories that the build file names. A build file that relied on that to reach a remote repository has to callpublishinstead.PublishOperation.repository(String)no longer resolves the name when it is called, so a name that isn't declared is reported when the publication runs rather than when the build file is constructed. Because the names live in their own list until then,PublishOperation.clearRepositories()is what clears a publication's repositories, clearing therepositories()list alone leaves the names.- A location has to be an absolute path or a URL. A relative path is no longer taken as one, so a build file that named one as a repository now has it treated as an undeclared name and skipped.
- A repository name that isn't declared is now reported as a warning and skipped. In 2.3.0 it became a repository at that relative path, so publishing to a name that was never declared wrote into a directory instead of saying so. A
bld.repo.property that doesn't hold a location is now refused with aRepositoryLocationInvalidException. - The
bldcache file is read and written as UTF-8.