Repository navigation
Fix MavenPublisher to support POM-only publications - #1574
Merged
Merged
Conversation
2 tasks done
vinnybod
added a commit
to confluentinc/rules_jvm_external
that referenced
this pull request
Oct 13, 2026
* Prefer getenv to env.get (bazel-contrib#1568) * update environment variable handling for pinning (bazel-contrib#1573) * Fix MavenPublisher to support POM-only publications (bazel-contrib#1574) * Bump the deps in the Spring Boot examples (bazel-contrib#1580) * Update remaining examples (bazel-contrib#1581) This involves rewriting the Android Kotlin app to avoid AppCompat as otherwise the `install` tag became a mess, and that's not what we're trying to demonstrate. * Update Gradle to 9.5.0 (bazel-contrib#1569) Gradle 9.x requires JVM 17 to run, so this also bumps the project's default Java toolchain in .bazelrc from 11 to 17. Downstream projects can continue targeting Java 11 with their own .bazelrc, though using the Gradle resolver will require JVM 17+. --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * Fix link to docs/bzlmod.md in README.md (bazel-contrib#1564) * Fix GitHub search query in README (bazel-contrib#1550) The `filename:` query was a part of a legacy implementation of code search. The current equivalent is `path:` [1]. [1] github/docs#24666 * fix: resolve concurrent NPE in ErrorReportingListener (bazel-contrib#1152) (bazel-contrib#1546) Use Collections.synchronizedList and synchronized block in getExceptions() to prevent NullPointerException when multiple threads add exceptions concurrently during Maven resolution. Extract common addExceptionIfPresent method with null-safe event check. Add ErrorReportingListenerTest to verify thread safety. Closes bazel-contrib#1152 * Run jvm_import jar tools with exec Java (bazel-contrib#1583) Invoke AddJarManifestEntry_deploy.jar with current_java_runtime in the exec configuration instead of executing the AddJarManifestEntry java_binary launcher. This preserves --tool_java_runtime_version and selects Java for the execution platform when the target and execution platforms differ. Treat AddJarManifestEntry_deploy.jar and JavaRuntimeInfo.files as action tools. Add jvm_import_uses_execution_platform_java_runtime_test with an Android s390x target platform. Android s390x has no Java runtime toolchain, so the test fails if StampJarManifest or CreateCompileJar resolves Java against the target platform. The test also verifies that both actions pass AddJarManifestEntry_deploy.jar to Java. * Refactor: carry a `ResolvedArtifact` for every resolution node when resolving (bazel-contrib#1585) Replace the `Map<Coordinates, Path>` side-channel on `ResolutionResult` with a `Map<Coordinates, ResolvedArtifact>` that has an entry for every node in the resolved graph. Each `ResolvedArtifact` holds its coordinates and an optional path, so "this node has no known binary" is represented explicitly rather than inferred from an absent map entry. This is a pure refactoring: the Maven and Gradle resolvers populate the new shape from exactly the information they already had, the downloader still receives the same set of known paths, and the lock file, its format, and the resolved-artifact hashes are all unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make `amend_artifact` also match BOMs (bazel-contrib#1586) `amend_artifact` previously searched only the `artifacts` list, so a BOM (declared via `install(boms = ...)` or split out of a `from_toml` `libs.versions.toml` via `bom_modules`) could not be amended. The amendment failed with "No artifact found matching coordinates" because BOMs are tracked in a separate list that the amendment never searched. `amend_artifact` now searches both the artifacts and boms lists, so a BOM's version and other properties can be adjusted through the same mechanism as a regular artifact (for example, force-pinning a BOM version so transitive deps can't silently upgrade it). Add unit tests covering amendment of artifacts, BOMs, and the no-match case. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * Allow boms to be defined in the gradle version catalogues (bazel-contrib#1543) * Apply Maven exclusions to generated deps (bazel-contrib#1594) * Fix BOM-only pinning (bazel-contrib#1592) * Fix null shasum artifacts in v3 locks (bazel-contrib#1591) * Preserve compound archive extensions when publishing (bazel-contrib#1590) * Add `publish-to-bcr` automation (bazel-contrib#1587) * Fix resolver NPE for no-binary artifacts (bazel-contrib#1595) * Fix TOML AAR overrides using original artifact copy targets (bazel-contrib#1600) * fix: stop Gradle daemons after dependency resolution (bazel-contrib#1598) Closing the ProjectConnection alone leaves the Tooling API's daemon running for reuse. Call disconnect() on the connector so the daemon is shut down once pinning completes. * Index top-level kotlin functions, properties and type aliases properly. (bazel-contrib#1599) Top-level Kotlin functions, properties, and type aliases compile into a synthetic <File>Kt facade, so they were invisible to the class-name index and could not be attributed to an artifact in split packages. Read them from the @kotlin.Metadata annotation via kotlin-metadata-jvm and fold the public ones into the class index under their Kotlin source names. * Skip package-info.class when indexing jars (bazel-contrib#1597) `package-info.class` files only hold package-level annotations and cannot be referenced from production code, so they should never appear in the indexed class set. * Don't deduplicate additional_coursier_options (bazel-contrib#1596) Co-authored-by: Nikolay <n.matyushin@tawasal.ae> * Enable RJE_UNSAFE_CACHE by default (bazel-contrib#1584) The shared cache is now used unless RJE_UNSAFE_CACHE is set to "0" or "false". The CLI flag --use_unsafe_shared_cache has been replaced by --use_unique_cache, which opts out of the shared cache. Maven and Gradle docs updated accordingly. Coursier behaviour is unchanged for now. --------- Co-authored-by: Claude <noreply@anthropic.com> * fix: make :outdated work when runfiles trees are disabled (bazel-contrib#1602) `bazel run @maven//:outdated` failed with "Unable to access jarfile" under --noenable_runfiles (the default on Windows) because the generated sh_binary passed cwd-relative rootpaths, which only resolve inside a materialised runfiles tree. Resolve the arguments with the Bash runfiles library instead, as :pin already does. Co-authored-by: Claude <noreply@anthropic.com> * Preserve Gradle variant identity in the lock graph (bazel-contrib#1576) The Gradle resolver was flattening multiple selected variants of the same module into a single dependency node. When a module was resolved both as its main jar and as test fixtures, we merged their outgoing dependencies and then stamped that merged child set onto both output coordinates. That can create self loops and main-to-test-fixtures back-edges in the generated lockfile, which Bazel cannot repair downstream. Fix this by keeping variant identity through resolution so each selected variant keeps its own dependency set. Variants are classified and artifacts are attached to them using Gradle capabilities, the canonical identity for feature variants, so any capability-based variant is handled, not just test fixtures. Requested test-fixtures classifiers resolve through Gradle's testFixtures(...) notation instead of being treated like an ad hoc classifier fetch. * feat: Support pluggable dependency download and metadata caching SPIs (bazel-contrib#1589) Provides pluggable SPIs for rules_jvm_external's dependency resolution, allowing custom download/caching and authentication implementations (such as integrating with Bazel's remote fetcher/downloader APIs) to be registered via classpath plugins. Key Changes: 1. Public API Targets & SPIs: - Created public interfaces for MetadataService, DependencyMetadata, and DownloadService. - Added a generic SpiLoader utility to load classpath SPI service implementations (ensuring at most one implementation is loaded per SPI). - Exposed custom classpath library loading via the new resolver_extra_dependencies attribute. - Decomposed the API targets into fine-grained libraries: :api_core, :download_service, :metadata_service, and :spi_loader. - Relocated the build definition closer to the sources in //resolver/src/main/java/com/github/bazelbuild/rules_jvm_external/resolver/BUILD. - Flattened public SPI classes into a single package (com.github.bazelbuild.rules_jvm_external.resolver) to prevent split-package issues and avoid spanning multiple packages. 2. Aether & Downloader SPI Integration: - Replaced Aether's default HTTP transport with a custom HttpDownloaderTransporterFactory, routing all POM, BOM, and metadata lookups through the pluggable DownloadService SPI. - Extracted HttpDownloaderTransporter into its own top-level package-private class. - Renamed DownloadService.download to get to match HTTP verb naming conventions and align with head. - Implemented null-safe defensive copying of collections in DependencyMetadata constructor using Set.copyOf/Map.copyOf. 3. Inline URL Credentials Handling: - Aether downloads are now routed through the pluggable DownloadService SPI backed by HttpDownloader without inline credentials support (making both resolution and downloading fail consistently). Users must configure credentials via .netrc instead. - Deleted the shouldDownloadOverHttpWithAuthenticationPassedInOnRepoUrl test from ResolverTestBase.java since that flow does not work and is explicitly unsupported. 4. Cleanup & Optimization: - Removed final modifier from SpiLoader class and refactored joining logic to use Guava Joiner. - Removed redundant metadata caches and unused resolver binaries. * fix: honour pinned versions in external resolvers (bazel-contrib#1606) * BOM/POM coordinates condition marked as `skipped` must not be turned into `http_file downloads (bazel-contrib#1604) * Use a UTF-8 locale for jvm_import jar actions (bazel-contrib#1610) * fix: force a single version per Gradle module when pinning (bazel-contrib#1608) Gradle selects one version per group:artifact and ignores classifiers, so forcing each classified root separately (e.g. a main jar and its test-fixtures jar at different versions) made resolution unsatisfiable. Group roots by module and force only the defining version: the unclassified root, or the highest classified request. Also stop the resolver plugin's detached-configuration retry from undermining pins: skip it when the main configuration fully resolved, and re-apply the forced modules when it runs, since detached configurations never see `configurations.all`. Co-Authored-By: Claude <noreply@anthropic.com> * Prepare for 7.1 release (bazel-contrib#1593) Making the example build under Bazel 9 needed protobuf pinned back to 33.4 (35.0 requires Bazel >= 8, which was breaking the 7.x cell), an explicit `rules_java` bazel_dep, and `load` statements for `java_library` and `java_proto_library` since Bazel 9 no longer autoloads them. * Return repo_metadata from repository rules (bazel-contrib#1616) * Remove -noverify (bazel-contrib#1620) -noverify was removed in JDK 27 (deprecated since JDK 13) and now causes the launcher to fail with an unrecognized option error. It was only needed for proguarded coursier JARs from very old releases: coursier/coursier#1245 * perf: speed up java export exclusions (bazel-contrib#1624) Signed-off-by: Simon Mavi Stewart <simon.m.stewart@gmail.com> * fix: Improve Gradle resolver console output (bazel-contrib#1623) * build: update rules_kotlin to 2.4.0 (bazel-contrib#1621) * feat: expose kt_defs.bzl via public bzl_library for stardoc (bazel-contrib#1626) * fix: make Gradle resolver cache writes race-tolerant (bazel-contrib#1615) When pinning a large dependency graph with resolver = "gradle", the pin aborted non-deterministically with FileAlreadyExistsException while copying a freshly-downloaded artifact into the local cache. The failing artifact differed from run to run: whichever one lost a race between parallel downloader threads. For the Gradle resolver, localRepository is the shared Gradle module cache, which the Gradle daemon and other worker threads write to concurrently. Downloader.performDownload cached downloads with Files.copy(REPLACE_EXISTING), which is not atomic: REPLACE_EXISTING only removes a target present at check time, so a target created in the TOCTOU window makes the copy fail. A plain copy also lets another worker observe a half-written cache file through the Files.exists check at the top of performDownload. Cache to a temp file in the destination directory, then atomically move it into place. These artifacts are content-addressed, so a destination another writer already produced is success, and FileAlreadyExistsException on the move is ignored. * Handle overrides for fileless artifacts (bazel-contrib#1625) * Pass COURSIER_CACHE to coursier when fetching unpinned repositories (bazel-contrib#1601) Coursier derives its default cache location from the JVM's `user.home`, which on Linux comes from the passwd database and ignores $HOME, while these rules derive the shared cache location from $HOME. When the two disagree (e.g. $HOME remapped to a network mount), repinning bypasses the shared cache and fails with "Error while trying to parse the path of file in the coursier cache". Pass the computed location to the spawned coursier process via COURSIER_CACHE, as the pinned flow already does. If no variable a cache location can be derived from is set, leave the environment untouched. Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix: don't fail resolution when an artifact has no sources jar (bazel-contrib#1614) When fetch_sources = True and an artifact publishes a main jar but no sources jar (for example the empty com.google.guava:listenablefuture jar that Guava depends on), the Maven and Gradle resolvers' shared download phase threw UriNotFoundException instead of treating the sources jar as absent, failing the whole resolution. Downloader.download now returns null for a missing sources/javadoc jar so the caller can skip it, matching the `if (sdm != null)` guard already in AbstractMain.getDependencyInfos. Adds a DownloaderTest unit reproducer plus end-to-end guava installs exercised via both the Maven and Gradle resolvers. * Use rules_pkg in the java-export example (bazel-contrib#1628) The example loaded `pkg_tar` from `@bazel_tools//tools/build_defs/pkg:pkg.bzl`, which has been deprecated in favor of rules_pkg for years and is slated for removal from `@bazel_tools`. * Encapsulate bzlmod dependency layering (bazel-contrib#1618) * Add support for AAR files to IndexJar (bazel-contrib#1490) Fixes bazel-contrib#1489 * fix: apply remaining bzlmod layering review feedback from bazel-contrib#1618 (bazel-contrib#1629) Filter testonly non-root artifacts before the conflicting-force check so that declarations layering drops cannot fail the build. Report equal-version force displacement with an RJE_VERBOSE-gated INFO diagnostic; the non-root declaration previously replaced the root's silently. Rename the addtional_artifact_message variable. * fix: honour pinned versions in layered coursier installs (bazel-contrib#1631) * fix(publish): Apparently we need a specific version of the publish yaml (bazel-contrib#1612) * chore: prep for the 7.2 release (bazel-contrib#1633) --------- Signed-off-by: Simon Mavi Stewart <simon.m.stewart@gmail.com> Co-authored-by: Andrius Bankauskas <and.bankauskas@gmail.com> Co-authored-by: Titus Fortner <titusfortner@users.noreply.github.com> Co-authored-by: Simon Mavi Stewart <simon.m.stewart@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Sergey Tyurin <sergey.v.tyurin@gmail.com> Co-authored-by: Collin Funk <collin.funk1@gmail.com> Co-authored-by: Tharaka De Silva <tharaka.uo@gmail.com> Co-authored-by: David Zbarsky <dzbarsky@gmail.com> Co-authored-by: Ben Lee <ben@ben.cm> Co-authored-by: Nikolay M <dolphinn@bk.ru> Co-authored-by: Nikolay <n.matyushin@tawasal.ae> Co-authored-by: JonathanPerry651 <jonathan.perry@gs.com> Co-authored-by: mikhail-0330 <145472039+mikhail-0330@users.noreply.github.com> Co-authored-by: Keith Smiley <keithbsmiley@gmail.com> Co-authored-by: timothy <387270+timothyklim@users.noreply.github.com> Co-authored-by: Ted Kaplan <tkaplan@roku.com> Co-authored-by: Vasilii Novozhilov <69043738+aNOOBisTheGod@users.noreply.github.com> Co-authored-by: vadikmironov <77026200+vadikmironov@users.noreply.github.com> Co-authored-by: Fabian Meumertzheim <fabian@meumertzhe.im> Co-authored-by: Petter Måhlén <pettermahlen@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MavenPublisher.runwith!mainArtifactPath.isEmpty(), mirroring theStrings.isNullOrEmpty(extraArtifacts)check immediately below it.testPublishLocalPomOnlycovering the POM-only publish path.maven_publish.bzl declares artifact as optional (line 125-127) and encodes "no artifact" as an empty string when generating the publisher script (line 43). maven_bom relies on this — both .publish and -dependencies.publish invoke maven_publish with only a pom (maven_bom.bzl:215, :238), since BOMs are pom with no jar.
Paths.get("") resolves to the working directory, and Files.readAllBytes(...) on a directory throws java.io.IOException: Is a directory, so every maven_bom publish failed.