{"id":15065255,"url":"https://github.com/bazel-contrib/rules_jvm_external","last_synced_at":"2025-05-15T07:04:47.939Z","repository":{"id":27171043,"uuid":"110725759","full_name":"bazel-contrib/rules_jvm_external","owner":"bazel-contrib","description":"Bazel rules to resolve, fetch and export Maven artifacts","archived":false,"fork":false,"pushed_at":"2025-03-18T16:28:49.000Z","size":19036,"stargazers_count":347,"open_issues_count":274,"forks_count":264,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-05-04T01:02:19.893Z","etag":null,"topics":["bazel","maven"],"latest_commit_sha":null,"homepage":"","language":"Starlark","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bazel-contrib.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"open_collective":"bazel-rules-authors-sig"}},"created_at":"2017-11-14T17:59:51.000Z","updated_at":"2025-04-30T22:05:29.000Z","dependencies_parsed_at":"2023-02-18T21:46:00.919Z","dependency_job_id":"66bdec3d-c06a-40e9-9730-e8b5c6777108","html_url":"https://github.com/bazel-contrib/rules_jvm_external","commit_stats":{"total_commits":703,"total_committers":119,"mean_commits":5.907563025210084,"dds":0.6600284495021337,"last_synced_commit":"534e62d14655e01048b90ef89ab1acaf0caa7348"},"previous_names":["bazel-contrib/rules_jvm_external","bazelbuild/rules_jvm_external"],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_jvm_external","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_jvm_external/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_jvm_external/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_jvm_external/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bazel-contrib","download_url":"https://codeload.github.com/bazel-contrib/rules_jvm_external/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253404995,"owners_count":21903113,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bazel","maven"],"created_at":"2024-09-25T00:35:50.757Z","updated_at":"2025-05-15T07:04:42.895Z","avatar_url":"https://github.com/bazel-contrib.png","language":"Starlark","funding_links":["https://opencollective.com/bazel-rules-authors-sig"],"categories":["Java"],"sub_categories":[],"readme":"# rules_jvm_external\n\nTransitive Maven artifact resolution and publishing rules for Bazel.\n\n* Main build: [![Build\nStatus](https://badge.buildkite.com/26d895f5525652e57915a607d0ecd3fc945c8280a0bdff83d9.svg?branch=master)](https://buildkite.com/bazel/rules-jvm-external)\n* Examples build: [![Build status](https://badge.buildkite.com/d1e93c6c5321c9f7d24c71d849f00542f4ac5c9eed763eca2d.svg)](https://buildkite.com/bazel/rules-jvm-external-examples)\n\n\nTable of Contents\n=================\n\n- [Features](#features)\n- [Examples](#examples)\n    - [Projects using rules_jvm_external](#projects-using-rules_jvm_external)\n- [Prerequisites](#prerequisites)\n- [Usage](#usage)\n    - [With bzlmod (Bazel 7 and above)](#with-bzlmod-bazel-7-and-above)\n    - [With WORKSPACE file (legacy)](#with-workspace-file-legacy)\n- [API Reference](#api-reference)\n- [Pinning artifacts and integration with Bazel's downloader](#pinning-artifacts-and-integration-with-bazels-downloader)\n    - [Updating `maven_install.json`](#updating-maven_installjson)\n    - [Requiring lock file repinning when the list of artifacts changes](#requiring-lock-file-repinning-when-the-list-of-artifacts-changes)\n    - [Custom location for `maven_install.json`](#custom-location-for-maven_installjson)\n    - [Multiple `maven_install.json` files](#multiple-maven_installjson-files)\n- [(Experimental) Support for Maven BOM files](#experimental-support-for-maven-bom-files)\n- [Generated targets](#generated-targets)\n- [Outdated artifacts](#outdated-artifacts)\n- [Advanced usage](#advanced-usage)\n    - [Fetch source JARs](#fetch-source-jars)\n    - [Checksum verification](#checksum-verification)\n    - [Using a custom Coursier download url](#using-a-custom-coursier-download-url)\n    - [`artifact` helper macro](#artifact-helper-macro)\n    - [`java_plugin_artifact` helper macro](#java_plugin_artifact-helper-macro)\n    - [Multiple `maven_install` declarations for isolated artifact version trees](#multiple-maven_install-declarations-for-isolated-artifact-version-trees)\n    - [Detailed dependency information specifications](#detailed-dependency-information-specifications)\n    - [Artifact exclusion](#artifact-exclusion)\n    - [Compile-only dependencies](#compile-only-dependencies)\n    - [Test-only dependencies](#test-only-dependencies)\n    - [Resolving user-specified and transitive dependency version conflicts](#resolving-user-specified-and-transitive-dependency-version-conflicts)\n    - [Overriding generated targets](#overriding-generated-targets)\n    - [Proxies](#proxies)\n    - [Repository aliases](#repository-aliases)\n    - [Repository remapping](#repository-remapping)\n    - [Hiding transitive dependencies](#hiding-transitive-dependencies)\n    - [Accessing transitive dependencies list](#accessing-transitive-dependencies-list)\n    - [Fetch and resolve timeout](#fetch-and-resolve-timeout)\n    - [Ignoring empty jars](#ignoring-empty-jars)\n    - [Duplicate artifact warning](#duplicate-artifact-warning)\n    - [Provide JVM options for artifact resolution](#provide-jvm-options-for-artifact-resolution)\n    - [Provide JVM options for Coursier with `COURSIER_OPTS`](#provide-jvm-options-for-coursier-with-coursier_opts)\n    - [Resolving issues with nonstandard system default JDKs](#resolving-issues-with-nonstandard-system-default-jdks)\n    - [Exporting and consuming artifacts from external repositories](#exporting-and-consuming-artifacts-from-external-repositories)\n    - [Publishing to External Repositories](#publishing-to-external-repositories)\n- [Configuring the dependency resolver](#configuring-the-dependency-resolver)\n    - [Common options](#common-options)\n    - [Configuring Coursier](#configuring-coursier)\n    - [Configuring Maven](#configuring-maven)\n- [IPv6 support](#ipv6-support)\n- [Developing this project](#developing-this-project)\n    - [Verbose / debug mode](#verbose--debug-mode)\n    - [Tests](#tests)\n    - [Installing the Android SDK on macOS](#installing-the-android-sdk-on-macos)\n    - [Generating documentation](#generating-documentation)\n\n## Features\n\n* MODULE.bazel bzlmod configuration (Bazel 7 and above) \n* WORKSPACE configuration\n* Artifact version resolution with Coursier or Maven\n* Import downloaded JAR, AAR, source JARs\n* Export built JARs to Maven repositories\n* Pin resolved artifacts with their SHA-256 checksums into a version-controllable JSON file\n* Custom Maven repositories\n* Private Maven repositories using `netrc` files\n* Integration with Bazel's downloader and caching mechanisms for sharing artifacts across Bazel workspaces\n* Versionless target labels for simpler dependency management\n* Ability to declare multiple sets of versioned artifacts\n* Supported on Windows, macOS, Linux\n\nGet the [latest release\nhere](https://github.com/bazelbuild/rules_jvm_external/releases/latest).\n\n## Examples\n\nYou can find examples in the [`examples/`](./examples/) directory.\n\n### Projects using rules_jvm_external\n\nFind other GitHub projects using `rules_jvm_external`\n[with this search query](https://github.com/search?p=1\u0026q=rules_jvm_external+filename%3A%2FWORKSPACE+filename%3A%5C.bzl\u0026type=Code).\n\n\n## Prerequisites\n\n* Bazel 6.4.0, up to the current LTS version.\n* Support for Bazel versions between `5.4` and `7.x` is only available on releases `6.x`.\n* Support for Bazel versions between `4.x` and `5.4` is only available on releases `5.x`.\n* Support for Bazel versions before `4.0.0` is only available on releases `4.2` or earlier.\n\n**Compatibility guideline:** This project aims to be backwards compatible with\nthe (current LTS - 2) version. If the current LTS version is 8, then we aim to\nsupport versions 6, 7 and 8.\n\n## Usage\n\n### With bzlmod (Bazel 7 and above)\n\nIf you are starting a new project, or your project is already using Bazel 7 and\nabove, we recommend using [`bzlmod`](https://bazel.build/external/overview) to\nmanage your external dependencies, including Maven dependencies with\n`rules_jvm_external`. It address several shortcomings of the `WORKSPACE`\nmechanism. If you are unable to use `bzlmod`, `rules_jvm_external` also supports\nthe `WORKSPACE` mechanism (see below).\n\nSee [bzlmod.md](./docs/bzlmod.md) for the usage instructions. bzlmod is\non-by-default in Bazel 7.0.\n\n### With WORKSPACE file (legacy)\n\nNOTE: WORKSPACE support is disabled by default in Bazel 8.0, and will be removed in Bazel 9.0.\n\nList the top-level Maven artifacts and servers in the WORKSPACE:\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\nRULES_JVM_EXTERNAL_TAG = \"4.5\"\nRULES_JVM_EXTERNAL_SHA = \"b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6\"\n\nhttp_archive(\n    name = \"rules_jvm_external\",\n    strip_prefix = \"rules_jvm_external-%s\" % RULES_JVM_EXTERNAL_TAG,\n    sha256 = RULES_JVM_EXTERNAL_SHA,\n    url = \"https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip\" % RULES_JVM_EXTERNAL_TAG,\n)\n\nload(\"@rules_jvm_external//:repositories.bzl\", \"rules_jvm_external_deps\")\n\nrules_jvm_external_deps()\n\nload(\"@rules_jvm_external//:setup.bzl\", \"rules_jvm_external_setup\")\n\nrules_jvm_external_setup()\n\nload(\"@rules_jvm_external//:defs.bzl\", \"maven_install\")\n\nmaven_install(\n    artifacts = [\n        \"junit:junit:4.12\",\n        \"androidx.test.espresso:espresso-core:3.1.1\",\n        \"org.hamcrest:hamcrest-library:1.3\",\n    ],\n    repositories = [\n        # Private repositories are supported through HTTP Basic auth\n        \"http://username:password@localhost:8081/artifactory/my-repository\",\n        \"https://maven.google.com\",\n        \"https://repo1.maven.org/maven2\",\n    ],\n)\n```\n\nCredentials for private repositories can also be specified using a property file\nor environment variables. See the [Coursier\ndocumentation](https://get-coursier.io/docs/other-credentials.html#property-file)\nfor more information.\n\n`rules_jvm_external_deps` uses a default list of maven repositories to download\n `rules_jvm_external`'s own dependencies from. Should you wish to change this,\n use the `repositories` parameter, and also set the path to the lock file:\n\n ```python\nrules_jvm_external_deps(\n    repositories = [\"https://mycorp.com/artifacts\"],\n    deps_lock_file = \"@//:rules_jvm_external_deps_install.json\")\nrules_jvm_external_setup()\n```\n\nIf you are using `bzlmod`, define an `install` tag in your root\n`MODULE.bazel` which overrides the values:\n\n```python\nmaven.install(\n    name = \"rules_jvm_external_deps\",\n    repositories = [\"https://mycorp.com/artifacts\"],\n    lock_file = \"//:rules_jvm_external_deps_install.json\",\n)\n```\n\nOnce these changes have been made, repin using `REPIN=1 bazel run\n@rules_jvm_external_deps//:pin` and commit the file to your version\ncontrol system (note that at this point you will need to maintain your\ncustomized `rules_jvm_external_deps_install.json`):\n\nNext, reference the artifacts in the BUILD file with their versionless label:\n\n```python\njava_library(\n    name = \"java_test_deps\",\n    exports = [\n        \"@maven//:junit_junit\",\n        \"@maven//:org_hamcrest_hamcrest_library\",\n    ],\n)\n\nandroid_library(\n    name = \"android_test_deps\",\n    exports = [\n        \"@maven//:junit_junit\",\n        \"@maven//:androidx_test_espresso_espresso_core\",\n    ],\n)\n```\n\nThe default label syntax for an artifact `foo.bar:baz-qux:1.2.3` is `@maven//:foo_bar_baz_qux`. That is,\n\n* All non-alphanumeric characters are substituted with underscores.\n* Only the group and artifact IDs are required.\n* The target is located in the `@maven` top level package (`@maven//`).\n\n## API Reference\n\nYou can find the complete API reference at [docs/api.md](docs/api.md).\n\n## Pinning artifacts and integration with Bazel's downloader\n\n`rules_jvm_external` supports pinning artifacts and their SHA-256 checksums into\na `maven_install.json` file that can be checked into your repository.\n\nWithout artifact pinning, in a clean checkout of your project, `rules_jvm_external`\nexecutes the full artifact resolution and fetching steps (which can take a bit of time)\nand does not verify the integrity of the artifacts against their checksums. The\ndownloaded artifacts also cannot be shared across Bazel workspaces.\n\nBy pinning artifact versions, you can get improved artifact resolution and build times,\nsince using `maven_install.json` enables `rules_jvm_external` to integrate with Bazel's\ndownloader that caches files on their sha256 checksums. It also improves resiliency and\nintegrity by tracking the sha256 checksums and original artifact urls in the\nJSON file.\n\nSince all artifacts are persisted locally in Bazel's cache, it means that\n**fully offline builds are possible** after the initial `bazel fetch @maven//...`.\nThe artifacts are downloaded with `http_file` which supports `netrc` for authentication.\nYour `~/.netrc` will be included automatically.\nTo pass machine login credentials in the ~/.netrc file to coursier, specify\n`use_credentials_from_home_netrc_file = True` in your `maven_install` rule.\nFor additional credentials, add them in the repository URLs passed to `maven_install`\n(so they will be included in the generated JSON).\nAlternatively, pass an array of `additional_netrc_lines` to `maven_install` for authentication with credentials from\noutside the workspace.\n\nTo get started with pinning artifacts, run the following command to generate the\ninitial `maven_install.json` at the root of your Bazel workspace:\n\n```\n$ bazel run @maven//:pin\n```\n\nThen, specify `maven_install_json` in `maven_install` and load\n`pinned_maven_install` from `@maven//:defs.bzl`:\n\n```python\nmaven_install(\n    # artifacts, repositories, ...\n    maven_install_json = \"//:maven_install.json\",\n)\n\nload(\"@maven//:defs.bzl\", \"pinned_maven_install\")\npinned_maven_install()\n```\n\n**Note:** The `//:maven_install.json` label assumes you have a BUILD file in\nyour project's root directory. If you do not have one, create an empty BUILD\nfile to fix issues you may see. See\n[#242](https://github.com/bazelbuild/rules_jvm_external/issues/242)\n\n**Note:** If you're using an older version of `rules_jvm_external` and\nhaven't repinned your dependencies, you may see a warning that you lock\nfile \"does not contain a signature of the required artifacts\" then don't\nworry: either ignore the warning or repin the dependencies.\n\n### Updating `maven_install.json`\n\nWhenever you make a change to the list of `artifacts` or `repositories` and want\nto update `maven_install.json`, run this command to re-pin the unpinned `@maven`\nrepository:\n\n```\n$ REPIN=1 bazel run @maven//:pin\n```\n\nWithout re-pinning, `maven_install` will not pick up the changes made to the\nWORKSPACE, as `maven_install.json` is now the source of truth.\n\n### Requiring lock file repinning when the list of artifacts changes\n\nIt can be easy to forget to update the `maven_install.json` lock file\nwhen updating artifacts in a `maven_install`. Normally,\nrules_jvm_external will print a warning to the console and continue\nthe build when this happens, but by setting the\n`fail_if_repin_required` attribute to `True`, this will be treated as\na build error, causing the build to fail. When this attribute is set,\nit is possible to update the `maven_install.json` file using:\n\n```shell\n# To repin everything:\nREPIN=1 bazel run @maven//:pin\n\n# To only repin rules_jvm_external:\nRULES_JVM_EXTERNAL_REPIN=1 bazel run @maven//:pin\n```\n\nAlternatively, it is also possible to modify the\n`fail_if_repin_required` attribute in your `WORKSPACE` file, run\n`bazel run @maven//:pin` and then reset the\n`fail_if_repin_required` attribute.\n\n### Custom location for `maven_install.json`\n\nYou can specify a custom location for `maven_install.json` by changing the\n`maven_install_json` attribute value to point to the new file label. For example:\n\n```python\nmaven_install(\n    name = \"maven_install_in_custom_location\",\n    artifacts = [\"com.google.guava:guava:27.0-jre\"],\n    repositories = [\"https://repo1.maven.org/maven2\"],\n    maven_install_json = \"@rules_jvm_external//tests/custom_maven_install:maven_install.json\",\n)\n\nload(\"@maven_install_in_custom_location//:defs.bzl\", \"pinned_maven_install\")\npinned_maven_install()\n```\n\nFuture artifact pinning updates to `maven_install.json` will overwrite the file\nat the specified path instead of creating a new one at the default root\ndirectory location.\n\n### Multiple `maven_install.json` files\n\nIf you have multiple `maven_install` declarations, you have to alias\n`pinned_maven_install` to another name to prevent redefinitions:\n\n```python\nmaven_install(\n    name = \"foo\",\n    maven_install_json = \"//:foo_maven_install.json\",\n    # ...\n)\n\nload(\"@foo//:defs.bzl\", foo_pinned_maven_install = \"pinned_maven_install\")\nfoo_pinned_maven_install()\n\nmaven_install(\n    name = \"bar\",\n    maven_install_json = \"//:bar_maven_install.json\",\n    # ...\n)\n\nload(\"@bar//:defs.bzl\", bar_pinned_maven_install = \"pinned_maven_install\")\nbar_pinned_maven_install()\n```\n\n## (Experimental) Support for Maven BOM files\n\nMaven BOMs can be used by using the `boms` attribute, for example:\n\n```starlark\nmaven.install(\n    boms = [\n        \"org.seleniumhq.selenium:selenium-bom:4.18.1\",\n    ],\n    artifacts = [\n        # This dependency is included in the `selenium-bom`, so we can omit the version number\n        \"org.seleniumhq.selenium:selenium-java\",\n    ],\n)\n```\n\n## Generated targets\n\nFor the `junit:junit` example, using `bazel query @maven//:all --output=build`, we can see that the rule generated these targets:\n\n```python\nalias(\n  name = \"junit_junit_4_12\",\n  actual = \"@maven//:junit_junit\",\n)\n\njvm_import(\n  name = \"junit_junit\",\n  jars = [\"@maven//:https/repo1.maven.org/maven2/junit/junit/4.12/junit-4.12.jar\"],\n  srcjar = \"@maven//:https/repo1.maven.org/maven2/junit/junit/4.12/junit-4.12-sources.jar\",\n  deps = [\"@maven//:org_hamcrest_hamcrest_core\"],\n  tags = [\"maven_coordinates=junit:junit:4.12\"],\n)\n\njvm_import(\n  name = \"org_hamcrest_hamcrest_core\",\n  jars = [\"@maven//:https/repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar\"],\n  srcjar = \"@maven//:https/repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar\",\n  deps = [],\n  tags = [\"maven_coordinates=org.hamcrest:hamcrest.library:1.3\"],\n)\n```\n\nThese targets can be referenced by:\n\n*   `@maven//:junit_junit`\n*   `@maven//:org_hamcrest_hamcrest_core`\n\n**Transitive classes**: To use a class from `hamcrest-core` in your test, it's not sufficient to just\ndepend on `@maven//:junit_junit` even though JUnit depends on Hamcrest. The compile classes are not exported\ntransitively, so your test should also depend on `@maven//:org_hamcrest_hamcrest_core`.\n\n**Original coordinates**: The generated `tags` attribute value also contains the original coordinates of\nthe artifact, which integrates with rules like [bazel-common's\n`pom_file`](https://github.com/google/bazel-common/blob/f1115e0f777f08c3cdb115526c4e663005bec69b/tools/maven/pom_file.bzl#L177)\nfor generating POM files. See the [`pom_file_generation`\nexample](examples/pom_file_generation/) for more information.\n\n## Outdated artifacts\n\nTo check for updates of artifacts, run the following command at the root of your Bazel workspace:\n\n```\n$ bazel run @maven//:outdated\n```\n\n## Advanced usage\n\n### Fetch source JARs\n\nTo download the source JAR alongside the main artifact JAR, set `fetch_sources =\nTrue` in `maven_install`:\n\n```python\nmaven_install(\n    artifacts = [\n        # ...\n    ],\n    repositories = [\n        # ...\n    ],\n    fetch_sources = True,\n)\n```\n\n### Checksum verification\n\nArtifact resolution will fail if a `SHA-1` or `MD5` checksum file for the\nartifact is missing in the repository. To disable this behavior, set\n`fail_on_missing_checksum = False` in `maven_install`:\n\n```python\nmaven_install(\n    artifacts = [\n        # ...\n    ],\n    repositories = [\n        # ...\n    ],\n    fail_on_missing_checksum = False,\n)\n```\n\n### Using a custom Coursier download url\n\nBy default bazel bootstraps Coursier via [the urls specificed in versions.bzl](private/versions.bzl).\nHowever in case they are not directly accessible in your environment, you can also specify a custom\nurl to download Coursier. For example:\n\n```\n$ bazel build @maven_with_unsafe_shared_cache//... --repo_env=COURSIER_URL='https://my_secret_host.com/vXYZ/coursier.jar'\n```\n\nPlease note it still requires the SHA to match.\n\n### `artifact` helper macro\n\nThe `artifact` macro translates the artifact's `group:artifact` coordinates to\nthe label of the versionless target. This target is an\n[alias](https://docs.bazel.build/versions/master/be/general.html#alias) that\npoints to the `java_import`/`aar_import` target in the `@maven` repository,\nwhich includes the transitive dependencies specified in the top level artifact's\nPOM file.\n\nFor example, `@maven//:junit_junit` is equivalent to `artifact(\"junit:junit\")`.\n\nTo use it, add the load statement to the top of your BUILD file:\n\n```python\nload(\"@rules_jvm_external//:defs.bzl\", \"artifact\")\n```\n\nFull `group:artifact:[packaging:[classifier:]]version` maven coordinates are also\nsupported and translate to corresponding versionless target.\n\nNote that usage of this macro makes BUILD file refactoring with tools like\n`buildozer` more difficult, because the macro hides the actual target label at\nthe syntax level.\n\n### `java_plugin_artifact` helper macro\n\nThe `java_plugin_artifact` macro finds a `java_plugin` target which can be used\nto run an annotation procesor from a particular artifact.\n\nFor example, if you pull `com.google.auto.value:auto-value` into a\n`maven_install`, you can use the `java_plugin_artifact` macro in the `plugins`\nattribute of a target like `java_library`:\n\n```python\njava_library(\n    name = \"some_lib\",\n    srcs = [\"SrcUsingAuto.java\"],\n    plugins = [\n        java_plugin_artifact(\"com.google.auto.value:auto-value\", \"com.google.auto.value.processor.AutoValueProcessor\"),\n    ],\n)\n```\n\n### Multiple `maven_install` declarations for isolated artifact version trees\n\nIf your WORKSPACE contains several projects that use different versions of the\nsame artifact, you can specify multiple `maven_install` declarations in the\nWORKSPACE, with a unique repository name for each of them.\n\nFor example, if you want to use the JRE version of Guava for a server app, and\nthe Android version for an Android app, you can specify two `maven_install`\ndeclarations:\n\n```python\nmaven_install(\n    name = \"server_app\",\n    artifacts = [\n        \"com.google.guava:guava:27.0-jre\",\n    ],\n    repositories = [\n        \"https://repo1.maven.org/maven2\",\n    ],\n)\n\nmaven_install(\n    name = \"android_app\",\n    artifacts = [\n        \"com.google.guava:guava:27.0-android\",\n    ],\n    repositories = [\n        \"https://repo1.maven.org/maven2\",\n    ],\n)\n```\n\nThis way, `rules_jvm_external` will invoke coursier to resolve artifact versions for\nboth repositories independent of each other. Coursier will fail if it encounters\nversion conflicts that it cannot resolve. The two Guava targets can then be used\nin BUILD files like so:\n\n```python\njava_binary(\n    name = \"my_server_app\",\n    srcs = ...\n    deps = [\n        # a versionless alias to @server_app//:com_google_guava_guava_27_0_jre\n        \"@server_app//:com_google_guava_guava\",\n    ]\n)\n\nandroid_binary(\n    name = \"my_android_app\",\n    srcs = ...\n    deps = [\n        # a versionless alias to @android_app//:com_google_guava_guava_27_0_android\n        \"@android_app//:com_google_guava_guava\",\n    ]\n)\n```\n\n### Detailed dependency information specifications\n\nAlthough you can always give a dependency as a Maven coordinate string,\noccasionally special handling is required in the form of additional directives\nto properly situate the artifact in the dependency tree. For example, a given\nartifact may need to have one of its dependencies excluded to prevent a\nconflict.\n\nThis situation is provided for by allowing the artifact to be specified as a map\ncontaining all of the required information. This map can express more\ninformation than the coordinate strings can, so internally the coordinate\nstrings are parsed into the artifact map with default values for the additional\nitems. To assist in generating the maps, you can pull in the file `specs.bzl`\nalongside `defs.bzl` and import the `maven` struct, which provides several\nhelper functions to assist in creating these maps. An example:\n\n```python\nload(\"@rules_jvm_external//:defs.bzl\", \"artifact\")\nload(\"@rules_jvm_external//:specs.bzl\", \"maven\")\n\nmaven_install(\n    artifacts = [\n        maven.artifact(\n            group = \"com.google.guava\",\n            artifact = \"guava\",\n            version = \"27.0-android\",\n            exclusions = [\n                ...\n            ]\n        ),\n        \"junit:junit:4.12\",\n        ...\n    ],\n    repositories = [\n        maven.repository(\n            \"https://some.private.maven.re/po\",\n            user = \"johndoe\",\n            password = \"example-password\"\n        ),\n        \"https://repo1.maven.org/maven2\",\n        ...\n    ],\n)\n```\n\nNote [when using `bzlmod`](docs/bzlmod.md) the syntax in `MODULE.bazel` is\ndifferent than shown above.\n\n### Artifact exclusion\n\nIf you want to exclude an artifact from the transitive closure of a top level\nartifact, specify its `group-id:artifact-id` in the `exclusions` attribute of\nthe `maven.artifact` helper:\n\n```python\nload(\"@rules_jvm_external//:specs.bzl\", \"maven\")\n\nmaven_install(\n    artifacts = [\n        maven.artifact(\n            group = \"com.google.guava\",\n            artifact = \"guava\",\n            version = \"27.0-jre\",\n            exclusions = [\n                maven.exclusion(\n                    group = \"org.codehaus.mojo\",\n                    artifact = \"animal-sniffer-annotations\"\n                ),\n                \"com.google.j2objc:j2objc-annotations\",\n            ]\n        ),\n        # ...\n    ],\n    repositories = [\n        # ...\n    ],\n)\n```\n\nYou can specify the exclusion using either the `maven.exclusion` helper or the\n`group-id:artifact-id` string directly.\n\nYou can also exclude artifacts globally using the `excluded_artifacts`\nattribute in `maven_install`:\n\n\n```python\nmaven_install(\n    artifacts = [\n        # ...\n    ],\n    repositories = [\n        # ...\n    ],\n    excluded_artifacts = [\n        \"com.google.guava:guava\",\n    ],\n)\n```\n\n### Compile-only dependencies\n\nIf you want to mark certain artifacts as compile-only dependencies, use the\n`neverlink` attribute in the `maven.artifact` helper:\n\n```python\nload(\"@rules_jvm_external//:specs.bzl\", \"maven\")\n\nmaven_install(\n    artifacts = [\n        maven.artifact(\"com.squareup\", \"javapoet\", \"1.11.0\", neverlink = True),\n    ],\n    # ...\n)\n```\n\nThis instructs `rules_jvm_external` to mark the generated target for\n`com.squareup:javapoet` with the `neverlink = True` attribute, making the\nartifact available only for compilation and not at runtime.\n\n### Test-only dependencies\n\nIf you want to mark certain artifacts as test-only dependencies, use the\n`testonly` attribute in the `maven.artifact` helper:\n\n```python\nload(\"@rules_jvm_external//:specs.bzl\", \"maven\")\n\nmaven_install(\n    artifacts = [\n        maven.artifact(\"junit\", \"junit\", \"4.13\", testonly = True),\n    ],\n    # ...\n)\n```\n\nThis instructs `rules_jvm_external` to mark the generated target for\n`junit:Junit` with the `testonly = True` attribute, making the\nartifact available only for tests (e.g. `java_test`), or targets specifically\nmarked as `testonly = True`.\n\n### Resolving user-specified and transitive dependency version conflicts\n\nUse the `version_conflict_policy` attribute to decide how to resolve conflicts\nbetween artifact versions specified in your `maven_install` rule and those\nimplicitly picked up as transitive dependencies.\n\nThe attribute value can be either `default` or `pinned`.\n\n`default`: use [Coursier's default algorithm](https://get-coursier.io/docs/other-version-handling)\nfor version handling.\n\n`pinned`: pin the versions of the artifacts that are explicitly specified in `maven_install`.\n\nFor example, pulling in guava transitively via google-cloud-storage resolves to\nguava-26.0-android.\n\n```python\nmaven_install(\n    name = \"pinning\",\n    artifacts = [\n        \"com.google.cloud:google-cloud-storage:1.66.0\",\n    ],\n    repositories = [\n        \"https://repo1.maven.org/maven2\",\n    ]\n)\n```\n\n```\n$ bazel query @pinning//:all | grep guava_guava\n@pinning//:com_google_guava_guava\n@pinning//:com_google_guava_guava_26_0_android\n```\n\nPulling in guava-27.0-android directly works as expected.\n\n```python\nmaven_install(\n    name = \"pinning\",\n    artifacts = [\n        \"com.google.cloud:google-cloud-storage:1.66.0\",\n        \"com.google.guava:guava:27.0-android\",\n    ],\n    repositories = [\n        \"https://repo1.maven.org/maven2\",\n    ]\n)\n```\n\n```\n$ bazel query @pinning//:all | grep guava_guava\n@pinning//:com_google_guava_guava\n@pinning//:com_google_guava_guava_27_0_android\n```\n\nPulling in guava-25.0-android (a lower version), resolves to guava-26.0-android. This is the default version conflict policy in action, where artifacts are resolved to the highest version.\n\n```python\nmaven_install(\n    name = \"pinning\",\n    artifacts = [\n        \"com.google.cloud:google-cloud-storage:1.66.0\",\n        \"com.google.guava:guava:25.0-android\",\n    ],\n    repositories = [\n        \"https://repo1.maven.org/maven2\",\n    ]\n)\n```\n\n```\n$ bazel query @pinning//:all | grep guava_guava\n@pinning//:com_google_guava_guava\n@pinning//:com_google_guava_guava_26_0_android\n```\n\nNow, if we add `version_conflict_policy = \"pinned\"`, we should see guava-25.0-android getting pulled instead. The rest of non-specified artifacts still resolve to the highest version in the case of version conflicts.\n\n```python\nmaven_install(\n    name = \"pinning\",\n    artifacts = [\n        \"com.google.cloud:google-cloud-storage:1.66.0\",\n        \"com.google.guava:guava:25.0-android\",\n    ],\n    repositories = [\n        \"https://repo1.maven.org/maven2\",\n    ]\n    version_conflict_policy = \"pinned\",\n)\n```\n\n```\n$ bazel query @pinning//:all | grep guava_guava\n@pinning//:com_google_guava_guava\n@pinning//:com_google_guava_guava_25_0_android\n```\n\nThere may be cases where you want the `default` pinning strategy, but\nwant one specific dependency to be pinned, no matter what. In these\ncases, you can use the `force_version` attribute on the\n`maven.artifact` helper to ensure this happens.\n\n```starlark\nmaven_install(\n    name = \"forcing_versions\",\n    artifacts = [\n        # Specify an ancient version of guava, and force its use. If we try to use `[23.3-jre]` as the version,\n        # the resolution will fail when using `coursier`\n        maven.artifact(\n            artifact = \"guava\",\n            force_version = True,\n            group = \"com.google.guava\",\n            version = \"23.3-jre\",\n        ),\n        # And something that depends on a more recent version of guava\n        \"xyz.rogfam:littleproxy:2.1.0\",\n    ],\n    repositories = [\n        \"https://repo1.maven.org/maven2\",\n    ],\n)\n```\n\nIn this case, once pinning is complete, guava `23.3-jre` will be selected.\n\n### Overriding generated targets\n\nYou can override the generated targets for artifacts with a target label of your\nchoice. For instance, if you want to provide your own definition of\n`@maven//:com_google_guava_guava` at `//third_party/guava:guava`, specify the\nmapping in the `override_targets` attribute:\n\n```python\nmaven_install(\n    name = \"pinning\",\n    artifacts = [\n        \"com.google.guava:guava:27.0-jre\",\n    ],\n    repositories = [\n        \"https://repo1.maven.org/maven2\",\n    ],\n    override_targets = {\n        \"com.google.guava:guava\": \"@//third_party/guava:guava\",\n    },\n)\n```\n\nNote that the target label contains `@//`, which tells Bazel to reference the\ntarget relative to your main workspace, instead of the `@maven` workspace.\n\nThe dependency that has been overridden is made available prefixed with\n`original_`. That is, in the example above, the version of Guava that was\nresolved could be accessed as `@maven//:original_com_google_guava_guava`.\nThe primary use case this is designed to support is to allow specific \ntargets to have additional dependencies added (eg. to ensure a default \nimplementation of key interfaces are available on the classpath without \nneeding to modify every target)\n\n### Proxies\n\nAs with other Bazel repository rules, the standard `http_proxy`, `https_proxy`\nand `no_proxy` environment variables (and their uppercase counterparts) are\nsupported.\n\n### Repository aliases\n\nMaven artifact rules like `maven_jar` and `jvm_import_external` generate targets\nlabels in the form of `@group_artifact//jar`, like `@com_google_guava_guava//jar`. This\nis different from the `@maven//:group_artifact` naming style used in this project.\n\nAs some Bazel projects depend on the `@group_artifact//jar` style labels, we\nprovide a `generate_compat_repositories` attribute in `maven_install`. If\nenabled, JAR artifacts can also be referenced using the `@group_artifact//jar`\ntarget label. For example, `@maven//:com_google_guava_guava` can also be\nreferenced using `@com_google_guava_guava//jar`.\n\nThe artifacts can also be referenced using the style used by\n`java_import_external` as `@group_artifact//:group_artifact` or\n`@group_artifact` for short.\n\n```python\nmaven_install(\n    artifacts = [\n        # ...\n    ],\n    repositories = [\n        # ...\n    ],\n    generate_compat_repositories = True\n)\n\nload(\"@maven//:compat.bzl\", \"compat_repositories\")\ncompat_repositories()\n```\n\n#### Repository remapping\n\nIf the `maven_jar` or `jvm_import_external` is not named according to `rules_jvm_external`'s\nconventions, you can apply\n[repository remapping](https://docs.bazel.build/versions/master/external.html#shadowing-dependencies)\nfrom the expected name to the new name for compatibility.\n\nFor example, if an external dependency uses `@guava//jar`, and `rules_jvm_external`\ngenerates `@com_google_guava_guava//jar`, apply the `repo_mapping` attribute to the external\nrepository WORKSPACE rule, like `http_archive` in this example:\n\n```python\nhttp_archive(\n    name = \"my_dep\",\n    repo_mapping = {\n        \"@guava\": \"@com_google_guava_guava\",\n    }\n    # ...\n)\n```\n\nWith `repo_mapping`, all references to `@guava//jar` in `@my_dep`'s BUILD files will be mapped\nto `@com_google_guava_guava//jar` instead.\n\n### Hiding transitive dependencies\n\nAs a convenience, transitive dependencies are visible to your build rules.\nHowever, this can lead to surprises when updating `maven_install`'s `artifacts`\nlist, since doing so may eliminate transitive dependencies from the build\ngraph.  To force rule authors to explicitly declare all directly referenced\nartifacts, use the `strict_visibility` attribute in `maven_install`:\n\n```python\nmaven_install(\n    artifacts = [\n        # ...\n    ],\n    repositories = [\n        # ...\n    ],\n    strict_visibility = True\n)\n```\n\nIt is also possible to change strict visibility value from default `//visibility:private`\nto a value specified by `strict_visibility_value` attribute.\n\n### Accessing transitive dependencies list\n\nIt is possible to retrieve full list of dependencies in the dependency tree, including\ntransitive, source, javadoc and other artifacts. `maven_artifacts` list contains full\nversioned maven coordinate strings of all dependencies.\n\nFor example:\n```python\nload(\"@maven//:defs.bzl\", \"maven_artifacts\")\n\nload(\"@rules_jvm_external//:defs.bzl\", \"artifact\")\nload(\"@rules_jvm_external//:specs.bzl\", \"parse\")\n\nall_jar_coordinates = [c for c in maven_artifacts if parse.parse_maven_coordinate(c).get(\"packaging\", \"jar\") == \"jar\"]\nall_jar_targets = [artifact(c) for c in all_jar_coordinates]\n\njava_library(\n  name = \"depends_on_everything\",\n  runtime_deps = all_jar_targets,\n)\n```\n\n### Fetch and resolve timeout\n\nThe default timeout to fetch and resolve artifacts is 600 seconds.  If you need\nto change this to resolve a large number of artifacts you can set the\n`resolve_timeout` attribute in `maven_install`:\n\n```python\nmaven_install(\n    artifacts = [\n        # ...\n    ],\n    repositories = [\n        # ...\n    ],\n    resolve_timeout = 900\n)\n```\n### Ignoring empty jars\n\nBy default, if any fetched jar is empty (has 0 bytes) the corresponding artifact will still be included in the dependency tree.\n\nIf you would like to avoid such artifacts, and treat jars that are empty (i.e. their checksum equals the checksum of an\nempty file) as if they were not found, you can set the `ignore_empty_files` attribute in `maven_install` to remove such\nartifacts from coursier's output:\n\n```python\nmaven_install(\n    artifacts = [\n        # ...\n    ],\n    repositories = [\n        # ...\n    ],\n    # ...\n    ignore_empty_files = True\n)\n```\n\nThis option may be useful if you see empty source jars when `fetch_sources` is enabled.\n\n\n### Duplicate artifact warning\n\nBy default you will be warned if there are duplicate artifacts in your artifact list. The `duplicate_version_warning` setting can be used to change this behavior. Use \"none\" to disable the warning and \"error\" to fail the build instead of warn.\n\n```python\nmaven_install(\n    artifacts = [\n        # ...\n    ],\n    repositories = [\n        # ...\n    ],\n    duplicate_version_warning = \"error\"\n)\n```\n\n### Provide JVM options for artifact resolution\n\nYou can set the `JDK_JAVA_OPTIONS` environment variable to provide additional JVM options to the artifact resolver.\n\n```python\nbuild --repo_env=JDK_JAVA_OPTIONS=-Djavax.net.ssl.trustStore=\u003cpath-to-cacerts\u003e\n```\ncan be added to your .bazelrc file if you need to specify custom cacerts for artifact resolution.\n\n### Provide JVM options for Coursier with `COURSIER_OPTS`\n\nYou can set up `COURSIER_OPTS` environment variable to provide some additional JVM options for Coursier.\nThis is a space-separated list of options.\n\nAssume you'd like to override Coursier's memory settings:\n\n```bash\nCOURSIER_OPTS=\"-Xms1g -Xmx4g\"\n```\n\n### Resolving issues with nonstandard system default JDKs\n\nTry to use OpenJDK explicitly if your machine or environment is set up to use a non-standard default implementation of the JDK and you encounter errors similar to the following:\n\n```\njava.lang.NullPointerException\n\tat java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)\n\tat java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)\n\tat java.base/java.lang.reflect.Field.get(Field.java:418)\n\tat org.robolectric.shadows.ShadowActivityThread$_ActivityThread_$$Reflector0.getActivities(Unknown Source)\n\tat org.robolectric.shadows.ShadowActivityThread.reset(ShadowActivityThread.java:277)\n\tat org.robolectric.Shadows.reset(Shadows.java:2499)\n\tat org.robolectric.android.internal.AndroidTestEnvironment.resetState(AndroidTestEnvironment.java:640)\n\tat org.robolectric.RobolectricTestRunner.lambda$finallyAfterTest$0(RobolectricTestRunner.java:361)\n\tat org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:86)\n\tat org.robolectric.RobolectricTestRunner.finallyAfterTest(RobolectricTestRunner.java:359)\n\tat org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:296)\n\tat org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:99)\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)\n\tat java.base/java.lang.Thread.run(Thread.java:830)\n```\n\nor\n\n```\njava.lang.UnsatisfiedLinkError: libstdc++.so.6: cannot open shared object file: No such file or directory\n\tat java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)\n\tat java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2444)\n\tat java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2500)\n\tat java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2716)\n\tat java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2629)\n\tat java.base/java.lang.Runtime.load0(Runtime.java:769)\n\tat java.base/java.lang.System.load(System.java:1840)\n\tat org.conscrypt.NativeLibraryUtil.loadLibrary(NativeLibraryUtil.java:52)\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:566)\n  ...\n```\n\n## Exporting and consuming artifacts from external repositories\n\nIf you're writing a library that has dependencies, you should define a constant that\nlists all of the artifacts that your library requires. For example:\n\n```python\n# my_library/BUILD\n# Public interface of the library\njava_library(\n  name = \"my_interface\",\n  deps = [\n    \"@maven//:junit_junit\",\n    \"@maven//:com_google_inject_guice\",\n  ],\n)\n```\n\n```python\n# my_library/library_deps.bzl\n# All artifacts required by the library\nMY_LIBRARY_ARTIFACTS = [\n  \"junit:junit:4.12\",\n  \"com.google.inject:guice:4.0\",\n]\n```\n\nUsers of your library can then load the constant in their `WORKSPACE` and add the\nartifacts to their `maven_install`. For example:\n\n```python\n# user_project/WORKSPACE\nload(\"@my_library//:library_deps.bzl\", \"MY_LIBRARY_ARTIFACTS\")\n\nmaven_install(\n  artifacts = [\n        \"junit:junit:4.11\",\n        \"com.google.guava:guava:26.0-jre\",\n  ] + MY_LIBRARY_ARTIFACTS,\n)\n```\n\n```python\n# user_project/BUILD\njava_library(\n  name = \"user_lib\",\n  deps = [\n    \"@my_library//:my_interface\",\n    \"@maven//:junit_junit\",\n  ],\n)\n```\n\nAny version conflicts or duplicate artifacts will resolved automatically.\n\n## Publishing to External Repositories\n\nIn order to publish an artifact from your repo to a maven repository, you\nmust first create a `java_export` target. This is similar to a regular\n`java_library`, but allows two additional parameters: the maven coordinates\nand an optional template file to use for the `pom.xml` file.\n\n```python\n# user_project/BUILD\nload(\"@rules_jvm_external//:defs.bzl\", \"java_export\")\n\njava_export(\n  name = \"exported_lib\",\n  maven_coordinates = \"com.example:project:0.0.1\",\n  pom_template = \"pom.tmpl\",  # You can omit this\n  srcs = glob([\"*.java\"]),\n  deps = [\n    \"//user_project/utils\",\n    \"@maven//:com_google_guava_guava\",\n  ],\n)\n```\n\nIf you wish to publish an artifact with Kotlin source code to a maven repository\nyou can use `kt_jvm_export`. This rule has the same arguments and generated\nrules as `java_export`, but uses `kt_jvm_library` instead of `java_library`.\n\n```python\n# user_project/BUILD\nload(\"@rules_jvm_external//:kt_defs.bzl\", \"kt_jvm_export\")\n\nkt_jvm_export(\n  name = \"exported_kt_lib\",\n  maven_coordinates = \"com.example:project:0.0.1\",\n  srcs = glob([\"*.kt\"]),\n)\n```\n\nIn order to publish the artifact, use `bazel run`:\n\n`bazel run --define \"maven_repo=file://$HOME/.m2/repository\" //user_project:exported_lib.publish`\n\nOr, to publish to (eg) Sonatype's OSS repo:\n\n```shell\nMAVEN_USER=example_user MAVEN_PASSWORD=hunter2 bazel run --stamp \\\n  --define \"maven_repo=https://oss.sonatype.org/service/local/staging/deploy/maven2\" \\\n  --define gpg_sign=true \\\n  //user_project:exported_lib.publish`\n```\n\nOr, to publish to a Google Cloud Storage:\n\n`bazel run --define \"maven_repo=gs://example-bucket/repository\" //user_project:exported_lib.publish`\n\nOr, to publish to an Amazon S3 bucket:\n\n`bazel run --define \"maven_repo=s3://example-bucket/repository\" //user_project:exported_lib.publish`\n\nOr, to publish to a GCP Artifact Registry:\n\n`bazel run --define \"maven_repo=artifactregistry://us-west1-maven.pkg.dev/project/repository\" //user_project:exported_lib.publish`\n\nWhen using the `gpg_sign` option, the current default key will be used for\nsigning, and the `gpg` binary needs to be installed on the machine.\n\n## Configuring the dependency resolver\n\n`rules_jvm_external` supports different mechanisms for dependency resolution.\nThese can be selected using the `resolver` attribute of `maven_install`. The\ndefault resolver is one backed by [coursier](https://get-coursier.io).\n\n### Common options\n\nAll resolvers understand the following environment variables:\n\n| Environment variable | Meaning                                                           |\n|----------------------|-------------------------------------------------------------------|\n| `RJE_VERBOSE`        | When set to `1` extra diagnostic logging will be sent to `stderr` |\n\n### Configuring Coursier\n\nThe default resolver is backed by [coursier](https://get-coursier.io), which\nis used in tools such as [sbt](https://www.scala-sbt.org). It supports being\nused without a lock file, but cannot handle resolutions which require Maven\nBOMs to be used. When using the coursier-backed resolver, the following\nenvironment variables are honoured:\n\n| Environment variable   | Meaning                                                                                                                                                                      |\n|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `COURSIER_CREDENTIALS` | [Documented here](https://get-coursier.io/docs/other-credentials#inline) on the coursier site. If set to an absolute path, this will be used for configuring the credentials |\n\n### Configuring Maven\n\nA Maven-backed resolver can be used by using setting the `resolver`\nattribute of `maven_install` to `maven`. This resolver requires the use of a\nlock file. For bootstrapping purposes, this file may simply be an empty\nfile. When using the maven-backed resolver, the following environment\nvariables are honoured:\n\n| Environment variable | Meaning                                                                                                                                                        |\n|----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `RJE_ASSUME_PRESENT` | Prevents the resolver from checking remote repositories to see if a dependency is present, and just assumes it is                                              |\n| `RJE_MAX_THREADS`    | Integer giving the maximum number of threads to use \u003cbr/\u003efor downloads. The default value is whichever is lower: the number of processors on the machine, or 5 |\n| `RJE_UNSAFE_CACHE`   | When set to `1` will use your `$HOME/.m2/repository` directory to speed up dependency resolution                                                               |\n\nUsing the unsafe cache option will use your local `$HOME/.m2/repository` as\na source for dependency resolutions, but will not include any local paths in\nthe generated lock file unless the `repositories` attribute contains `m2local`.\n\nThe Maven-backed resolver will use credentials stored in a `$HOME/.netrc`\nfile when performing dependency resolution\n\n## IPv6 support\n\nCertain IPv4/IPv6 dual-stack environments may require flags to override the default settings for downloading dependencies, for both Bazel's native downloader and Coursier as a downloader:\n\nAdd:\n\n* `startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true` to your `.bazelrc` file for Bazel's native downloader.\n* `-Djava.net.preferIPv6Addresses=true to the `COURSIER_OPTS` environment variable to provide JVM options for Coursier.\n\nFor more information, read the [official docs for IPv6 support in Bazel](https://bazel.build/docs/external#support-for-ipv6).\n\n## Developing this project\n\n### Verbose / debug mode\n\nSet the `RJE_VERBOSE` environment variable to `true` to print `coursier`'s verbose\noutput. For example:\n\n```\n$ RJE_VERBOSE=true bazel run @maven//:pin\n```\n\n### Tests\n\nIn order to run tests, your system must have an Android SDK installed. You can install the Android SDK using [Android Studio](https://developer.android.com/studio), or through most system package managers.\n\n```\n$ bazel test //...\n```\n\n#### Installing the Android SDK on macOS\n\nThe instructions for installing the Android SDK on macOS can be hard\nto find, but if you're comfortable using [HomeBrew](https://brew.sh),\nthe following steps will install what you need and set up the\n`ANDROID_HOME` environment variable that's required in order to run\n`rules_jvm_external`'s own tests.\n\n```\nbrew install android-commandlinetools\nexport ANDROID_HOME=\"$(brew --prefix)/share/android-commandlinetools\"\nsdkmanager \"build-tools;33.0.1\" \"cmdline-tools;latest\" \"ndk;21.4.7075529\" \"platform-tools\" \"platforms;android-33\"\nexport ANDROID_NDK_HOME=\"$ANDROID_HOME/ndk/21.4.7075529\"\n```\n\nYou can add the `export ANDROID_HOME` to your `.zshrc` or similar\nconfig file.\n\n\n### Generating documentation\n\nUse [Stardoc](https://skydoc.bazel.build/docs/getting_started_stardoc.html) to\ngenerate API documentation in the [docs](docs/) directory using\n[generate_docs.sh](scripts/generate_docs.sh).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbazel-contrib%2Frules_jvm_external","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbazel-contrib%2Frules_jvm_external","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbazel-contrib%2Frules_jvm_external/lists"}