- Notifications
You must be signed in to change notification settings - Fork0
Bazel rules to resolve, fetch and export Maven artifacts
License
kotlaja/rules_jvm_external
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Transitive Maven artifact resolution and publishing rules for Bazel.
- rules_jvm_external
- Features
- Usage
- API Reference
- Pinning artifacts and integration with Bazel's downloader
- Generated targets
- Outdated artifacts
- Advanced usage
- Fetch source JARs
- Checksum verification
- artifact helper macro
- Multiple maven_install declarations for isolated artifact version trees
- Detailed dependency information specifications
- Artifact exclusion
- Compile-only dependencies
- Resolving user-specified and transitive dependency version conflicts
- Overriding generated targets
- Proxies
- Repository aliases
- Hiding transitive dependencies
- Fetch and resolve timeout
- Jetifier
- Duplicate artifact warning
- Resolving issues with nonstandard system default JDKs
- Exporting and consuming artifacts from external repositories
- Publishing to external repositories
- Demo
- Projects using rules_jvm_external
- Generating documentation
- WORKSPACE configuration
- JAR, AAR, source JARs
- Custom Maven repositories
- Private Maven repositories with HTTP Basic Authentication
- Artifact version resolution with Coursier
- Integration with Bazel's downloader and caching mechanisms for sharing artifacts across Bazel workspaces
- Pin resolved artifacts with their SHA-256 checksums into a version-controllable JSON file
- Versionless target labels for simpler dependency management
- Ability to declare multiple sets of versioned artifacts
- Supported on Windows, macOS, Linux
Get thelatest releasehere.
- Bazel 4.0.0 and above
Support for Bazel versions before4.0.0 is only available on rules_jvm_external releases4.2 or earlier.
New: on Bazel 6, you can use bzlmod instead of following directions below.Seebzlmod.Expect rough edges and incomplete support as bzlmod is still a new feature as of early 2023.Note, bzlmod is expected to be on-by-default in Bazel 7.0.
List the top-level Maven artifacts and servers in the WORKSPACE:
load("@bazel_tools//tools/build_defs/repo:http.bzl","http_archive")RULES_JVM_EXTERNAL_TAG="4.5"RULES_JVM_EXTERNAL_SHA="b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6"http_archive(name="rules_jvm_external",strip_prefix="rules_jvm_external-%s"%RULES_JVM_EXTERNAL_TAG,sha256=RULES_JVM_EXTERNAL_SHA,url="https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip"%RULES_JVM_EXTERNAL_TAG,)load("@rules_jvm_external//:repositories.bzl","rules_jvm_external_deps")rules_jvm_external_deps()load("@rules_jvm_external//:setup.bzl","rules_jvm_external_setup")rules_jvm_external_setup()load("@rules_jvm_external//:defs.bzl","maven_install")maven_install(artifacts= ["junit:junit:4.12","androidx.test.espresso:espresso-core:3.1.1","org.hamcrest:hamcrest-library:1.3", ],repositories= [# Private repositories are supported through HTTP Basic auth"http://username:password@localhost:8081/artifactory/my-repository","https://maven.google.com","https://repo1.maven.org/maven2", ],)
Credentials for private repositories can also be specified using a property fileor environment variables. See theCoursierdocumentationfor more information.
rules_jvm_external_deps uses a default list of maven repositories to downloadrules_jvm_external's own dependencies from. Should you wish to change this,use therepositories parameter:
rules_jvm_external_deps(repositories= ["https://mycorp.com/artifacts"])rules_jvm_external_setup()
Next, reference the artifacts in the BUILD file with their versionless label:
java_library(name="java_test_deps",exports= ["@maven//:junit_junit","@maven//:org_hamcrest_hamcrest_library", ],)android_library(name="android_test_deps",exports= ["@maven//:junit_junit","@maven//:androidx_test_espresso_espresso_core", ],)
The default label syntax for an artifactfoo.bar:baz-qux:1.2.3 is@maven//:foo_bar_baz_qux. That is,
- All non-alphanumeric characters are substituted with underscores.
- Only the group and artifact IDs are required.
- The target is located in the
@maventop level package (@maven//).
You can find the complete API reference atdocs/api.md.
rules_jvm_external supports pinning artifacts and their SHA-256 checksums intoamaven_install.json file that can be checked into your repository.
Without artifact pinning, in a clean checkout of your project,rules_jvm_externalexecutes the full artifact resolution and fetching steps (which can take a bit of time)and does not verify the integrity of the artifacts against their checksums. Thedownloaded artifacts also cannot be shared across Bazel workspaces.
By pinning artifact versions, you can get improved artifact resolution and build times,since usingmaven_install.json enablesrules_jvm_external to integrate with Bazel'sdownloader that caches files on their sha256 checksums. It also improves resiliency andintegrity by tracking the sha256 checksums and original artifact urls in theJSON file.
Since all artifacts are persisted locally in Bazel's cache, it means thatfully offline builds are possible after the initialbazel fetch @maven//....The artifacts are downloaded withhttp_file which supportsnetrc for authentication.Your~/.netrc will be included automatically.To pass machine login credentials in the ~/.netrc file to coursier, specifyuse_credentials_from_home_netrc_file = True in yourmaven_install rule.For additional credentials, add them in the repository URLs passed tomaven_install(so they will be included in the generated JSON).Alternatively, pass an array ofadditional_netrc_lines tomaven_install for authentication with credentials fromoutside the workspace.
To get started with pinning artifacts, run the following command to generate theinitialmaven_install.json at the root of your Bazel workspace:
$ bazel run @maven//:pinThen, specifymaven_install_json inmaven_install and loadpinned_maven_install from@maven//:defs.bzl:
maven_install(# artifacts, repositories, ...maven_install_json="//:maven_install.json",)load("@maven//:defs.bzl","pinned_maven_install")pinned_maven_install()
Note: The//:maven_install.json label assumes you have a BUILD file inyour project's root directory. If you do not have one, create an empty BUILDfile to fix issues you may see. See#242
Note: If you're using an older version ofrules_jvm_external andhaven't repinned your dependencies, you may see a warning that you lockfile "does not contain a signature of the required artifacts" then don'tworry: either ignore the warning or repin the dependencies.
Whenever you make a change to the list ofartifacts orrepositories and wantto updatemaven_install.json, run this command to re-pin the unpinned@mavenrepository:
$ bazel run @unpinned_maven//:pinWithout re-pinning,maven_install will not pick up the changes made to theWORKSPACE, asmaven_install.json is now the source of truth.
Note that the repository is@unpinned_maven instead of@maven. When usingartifact pinning, eachmaven_install repository (e.g.@maven) will beaccompanied by an unpinned repository. This repository name has the@unpinned_prefix (e.g.@unpinned_maven or@unpinned_<your_maven_install_name>). Forexample, if yourmaven_install is named@foo,@unpinned_foo will becreated.
It can be easy to forget to update themaven_install.json lock filewhen updating artifacts in amaven_install. Normally,rules_jvm_external will print a warning to the console and continuethe build when this happens, but by setting thefail_if_repin_required attribute toTrue, this will be treated asa build error, causing the build to fail. When this attribute is set,it is possible to update themaven_install.json file using:
# To repin everything:REPIN=1 bazel run @unpinned_maven//:pin# To only repin rules_jvm_external:RULES_JVM_EXTERNAL_REPIN=1 bazel run @unpinned_maven//:pin
Alternatively, it is also possible to modify thefail_if_repin_required attribute in yourWORKSPACE file, runbazel run @unpinned_maven//:pin and then reset thefail_if_repin_required attribute.
You can specify a custom location formaven_install.json by changing themaven_install_json attribute value to point to the new file label. For example:
maven_install(name="maven_install_in_custom_location",artifacts= ["com.google.guava:guava:27.0-jre"],repositories= ["https://repo1.maven.org/maven2"],maven_install_json="@rules_jvm_external//tests/custom_maven_install:maven_install.json",)load("@maven_install_in_custom_location//:defs.bzl","pinned_maven_install")pinned_maven_install()
Future artifact pinning updates tomaven_install.json will overwrite the fileat the specified path instead of creating a new one at the default rootdirectory location.
If you have multiplemaven_install declarations, you have to aliaspinned_maven_install to another name to prevent redefinitions:
maven_install(name="foo",maven_install_json="//:foo_maven_install.json",# ...)load("@foo//:defs.bzl",foo_pinned_maven_install="pinned_maven_install")foo_pinned_maven_install()maven_install(name="bar",maven_install_json="//:bar_maven_install.json",# ...)load("@bar//:defs.bzl",bar_pinned_maven_install="pinned_maven_install")bar_pinned_maven_install()
For thejunit:junit example, usingbazel query @maven//:all --output=build, we can see that the rule generated these targets:
alias(name="junit_junit_4_12",actual="@maven//:junit_junit",)jvm_import(name="junit_junit",jars= ["@maven//:https/repo1.maven.org/maven2/junit/junit/4.12/junit-4.12.jar"],srcjar="@maven//:https/repo1.maven.org/maven2/junit/junit/4.12/junit-4.12-sources.jar",deps= ["@maven//:org_hamcrest_hamcrest_core"],tags= ["maven_coordinates=junit:junit:4.12"],)jvm_import(name="org_hamcrest_hamcrest_core",jars= ["@maven//:https/repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar"],srcjar="@maven//:https/repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar",deps= [],tags= ["maven_coordinates=org.hamcrest:hamcrest.library:1.3"],)
These targets can be referenced by:
@maven//:junit_junit@maven//:org_hamcrest_hamcrest_core
Transitive classes: To use a class fromhamcrest-core in your test, it's not sufficient to justdepend on@maven//:junit_junit even though JUnit depends on Hamcrest. The compile classes are not exportedtransitively, so your test should also depend on@maven//:org_hamcrest_hamcrest_core.
Original coordinates: The generatedtags attribute value also contains the original coordinates ofthe artifact, which integrates with rules likebazel-common'spom_filefor generating POM files. See thepom_file_generationexample for more information.
To check for updates of artifacts, run the following command at the root of your Bazel workspace:
$ bazel run @maven//:outdatedTo download the source JAR alongside the main artifact JAR, setfetch_sources = True inmaven_install:
maven_install(artifacts= [# ... ],repositories= [# ... ],fetch_sources=True,)
Artifact resolution will fail if aSHA-1 orMD5 checksum file for theartifact is missing in the repository. To disable this behavior, setfail_on_missing_checksum = False inmaven_install:
maven_install(artifacts= [# ... ],repositories= [# ... ],fail_on_missing_checksum=False,)
By default bazel bootstraps Coursier viathe urls specificed in versions.bzl.However in case they are not directly accessible in your environment, you can also specify a customurl to download Coursier. For example:
$ bazel build @maven_with_unsafe_shared_cache//... --repo_env=COURSIER_URL='https://my_secret_host.com/vXYZ/coursier.jar'Please note it still requires the SHA to match.
Theartifact macro translates the artifact'sgroup:artifact coordinates tothe label of the versionless target. This target is analias thatpoints to thejava_import/aar_import target in the@maven repository,which includes the transitive dependencies specified in the top level artifact'sPOM file.
For example,@maven//:junit_junit is equivalent toartifact("junit:junit").
To use it, add the load statement to the top of your BUILD file:
load("@rules_jvm_external//:defs.bzl","artifact")
Fullgroup:artifact:[packaging:[classifier:]]version maven coordinates are alsosupported and translate to corresponding versionless target.
Note that usage of this macro makes BUILD file refactoring with tools likebuildozer more difficult, because the macro hides the actual target label atthe syntax level.
If your WORKSPACE contains several projects that use different versions of thesame artifact, you can specify multiplemaven_install declarations in theWORKSPACE, with a unique repository name for each of them.
For example, if you want to use the JRE version of Guava for a server app, andthe Android version for an Android app, you can specify twomaven_installdeclarations:
maven_install(name="server_app",artifacts= ["com.google.guava:guava:27.0-jre", ],repositories= ["https://repo1.maven.org/maven2", ],)maven_install(name="android_app",artifacts= ["com.google.guava:guava:27.0-android", ],repositories= ["https://repo1.maven.org/maven2", ],)
This way,rules_jvm_external will invoke coursier to resolve artifact versions forboth repositories independent of each other. Coursier will fail if it encountersversion conflicts that it cannot resolve. The two Guava targets can then be usedin BUILD files like so:
java_binary(name="my_server_app",srcs= ...deps= [# a versionless alias to @server_app//:com_google_guava_guava_27_0_jre"@server_app//:com_google_guava_guava", ])android_binary(name="my_android_app",srcs= ...deps= [# a versionless alias to @android_app//:com_google_guava_guava_27_0_android"@android_app//:com_google_guava_guava", ])
Although you can always give a dependency as a Maven coordinate string,occasionally special handling is required in the form of additional directivesto properly situate the artifact in the dependency tree. For example, a givenartifact may need to have one of its dependencies excluded to prevent aconflict.
This situation is provided for by allowing the artifact to be specified as a mapcontaining all of the required information. This map can express moreinformation than the coordinate strings can, so internally the coordinatestrings are parsed into the artifact map with default values for the additionalitems. To assist in generating the maps, you can pull in the filespecs.bzlalongsidedefs.bzl and import themaven struct, which provides severalhelper functions to assist in creating these maps. An example:
load("@rules_jvm_external//:defs.bzl","artifact")load("@rules_jvm_external//:specs.bzl","maven")maven_install(artifacts= [maven.artifact(group="com.google.guava",artifact="guava",version="27.0-android",exclusions= [ ... ] ),"junit:junit:4.12", ... ],repositories= [maven.repository("https://some.private.maven.re/po",user="johndoe",password="example-password" ),"https://repo1.maven.org/maven2", ... ],)
If you want to exclude an artifact from the transitive closure of a top levelartifact, specify itsgroup-id:artifact-id in theexclusions attribute ofthemaven.artifact helper:
load("@rules_jvm_external//:specs.bzl","maven")maven_install(artifacts= [maven.artifact(group="com.google.guava",artifact="guava",version="27.0-jre",exclusions= [maven.exclusion(group="org.codehaus.mojo",artifact="animal-sniffer-annotations" ),"com.google.j2objc:j2objc-annotations", ] ),# ... ],repositories= [# ... ],)
You can specify the exclusion using either themaven.exclusion helper or thegroup-id:artifact-id string directly.
You can also exclude artifacts globally using theexcluded_artifactsattribute inmaven_install:
maven_install(artifacts= [# ... ],repositories= [# ... ],excluded_artifacts= ["com.google.guava:guava", ],)
If you want to mark certain artifacts as compile-only dependencies, use theneverlink attribute in themaven.artifact helper:
load("@rules_jvm_external//:specs.bzl","maven")maven_install(artifacts= [maven.artifact("com.squareup","javapoet","1.11.0",neverlink=True), ],# ...)
This instructsrules_jvm_external to mark the generated target forcom.squareup:javapoet with theneverlink = True attribute, making theartifact available only for compilation and not at runtime.
If you want to mark certain artifacts as test-only dependencies, use thetestonly attribute in themaven.artifact helper:
load("@rules_jvm_external//:specs.bzl","maven")maven_install(artifacts= [maven.artifact("junit","junit","4.13",testonly=True), ],# ...)
This instructsrules_jvm_external to mark the generated target forjunit:Junit with thetestonly = True attribute, making theartifact available only for tests (e.g.java_test), or targets specificallymarked astestonly = True.
Use theversion_conflict_policy attribute to decide how to resolve conflictsbetween artifact versions specified in yourmaven_install rule and thoseimplicitly picked up as transitive dependencies.
The attribute value can be eitherdefault orpinned.
default: useCoursier's default algorithmfor version handling.
pinned: pin the versions of the artifacts that are explicitly specified inmaven_install.
For example, pulling in guava transitively via google-cloud-storage resolves toguava-26.0-android.
maven_install(name="pinning",artifacts= ["com.google.cloud:google-cloud-storage:1.66.0", ],repositories= ["https://repo1.maven.org/maven2", ])
$ bazel query @pinning//:all | grep guava_guava@pinning//:com_google_guava_guava@pinning//:com_google_guava_guava_26_0_androidPulling in guava-27.0-android directly works as expected.
maven_install(name="pinning",artifacts= ["com.google.cloud:google-cloud-storage:1.66.0","com.google.guava:guava:27.0-android", ],repositories= ["https://repo1.maven.org/maven2", ])
$ bazel query @pinning//:all | grep guava_guava@pinning//:com_google_guava_guava@pinning//:com_google_guava_guava_27_0_androidPulling 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.
maven_install(name="pinning",artifacts= ["com.google.cloud:google-cloud-storage:1.66.0","com.google.guava:guava:25.0-android", ],repositories= ["https://repo1.maven.org/maven2", ])
$ bazel query @pinning//:all | grep guava_guava@pinning//:com_google_guava_guava@pinning//:com_google_guava_guava_26_0_androidNow, if we addversion_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.
maven_install(name="pinning",artifacts= ["com.google.cloud:google-cloud-storage:1.66.0","com.google.guava:guava:25.0-android", ],repositories= ["https://repo1.maven.org/maven2", ]version_conflict_policy="pinned",)
$ bazel query @pinning//:all | grep guava_guava@pinning//:com_google_guava_guava@pinning//:com_google_guava_guava_25_0_androidYou can override the generated targets for artifacts with a target label of yourchoice. For instance, if you want to provide your own definition of@maven//:com_google_guava_guava at//third_party/guava:guava, specify themapping in theoverride_targets attribute:
maven_install(name="pinning",artifacts= ["com.google.guava:guava:27.0-jre", ],repositories= ["https://repo1.maven.org/maven2", ],override_targets= {"com.google.guava:guava":"@//third_party/guava:guava", },)
Note that the target label contains@//, which tells Bazel to reference thetarget relative to your main workspace, instead of the@maven workspace.
As with other Bazel repository rules, the standardhttp_proxy,https_proxyandno_proxy environment variables (and their uppercase counterparts) aresupported.
Maven artifact rules likemaven_jar andjvm_import_external generate targetslabels in the form of@group_artifact//jar, like@com_google_guava_guava//jar. Thisis different from the@maven//:group_artifact naming style used in this project.
As some Bazel projects depend on the@group_artifact//jar style labels, weprovide agenerate_compat_repositories attribute inmaven_install. Ifenabled, JAR artifacts can also be referenced using the@group_artifact//jartarget label. For example,@maven//:com_google_guava_guava can also bereferenced using@com_google_guava_guava//jar.
The artifacts can also be referenced using the style used byjava_import_external as@group_artifact//:group_artifact or@group_artifact for short.
maven_install(artifacts= [# ... ],repositories= [# ... ],generate_compat_repositories=True)load("@maven//:compat.bzl","compat_repositories")compat_repositories()
If themaven_jar orjvm_import_external is not named according torules_jvm_external'sconventions, you can applyrepository remappingfrom the expected name to the new name for compatibility.
For example, if an external dependency uses@guava//jar, andrules_jvm_externalgenerates@com_google_guava_guava//jar, apply therepo_mapping attribute to the externalrepository WORKSPACE rule, likehttp_archive in this example:
http_archive(name="my_dep",repo_mapping= {"@guava":"@com_google_guava_guava", }# ...)
Withrepo_mapping, all references to@guava//jar in@my_dep's BUILD files will be mappedto@com_google_guava_guava//jar instead.
As a convenience, transitive dependencies are visible to your build rules.However, this can lead to surprises when updatingmaven_install'sartifactslist, since doing so may eliminate transitive dependencies from the buildgraph. To force rule authors to explicitly declare all directly referencedartifacts, use thestrict_visibility attribute inmaven_install:
maven_install(artifacts= [# ... ],repositories= [# ... ],strict_visibility=True)
It is also possible to change strict visibility value from default//visibility:privateto a value specified bystrict_visibility_value attribute.
It is possible to retrieve full list of dependencies in the dependency tree, includingtransitive, source, javadoc and other artifacts.maven_artifacts list contains fullversioned maven coordinate strings of all dependencies.
For example:
load("@maven//:defs.bzl","maven_artifacts")load("@rules_jvm_external//:defs.bzl","artifact")load("@rules_jvm_external//:specs.bzl","parse")all_jar_coordinates= [cforcinmaven_artifactsifparse.parse_maven_coordinate(c).get("packaging","jar")=="jar"]all_jar_targets= [artifact(c)forcinall_jar_coordinates]java_library(name="depends_on_everything",runtime_deps=all_jar_targets,)
The default timeout to fetch and resolve artifacts is 600 seconds. If you needto change this to resolve a large number of artifacts you can set theresolve_timeout attribute inmaven_install:
maven_install(artifacts= [# ... ],repositories= [# ... ],resolve_timeout=900)
As part of theAndroidJetpackmigration, convert legacy Android support library (com.android.support)libraries to rely on new AndroidX packages using theJetifier tool.Enable jetification by specifyingjetify = True inmaven_install.Control which artifacts to jetify withjetify_include_list — list of artifacts that need to be jetified ingroupId:artifactId format.By default all artifacts are jetified ifjetify is set to True.
NOTE: There is a performance penalty to using jetifier due to modifying fetched binaries, fetchingadditionalAndroidX artifacts, and modifying the maven dependency graph.
maven_install(artifacts= [# ... ],repositories= [# ... ],jetify=True,# Optionaljetify_include_list= ["exampleGroupId:exampleArtifactId", ],)
By default you will be warned if there are duplicate artifacts in your artifact list. Theduplicate_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.
maven_install(artifacts= [# ... ],repositories= [# ... ],duplicate_version_warning="error")
You can set upCOURSIER_OPTS environment variable to provide some additional JVM options for Coursier.This is a space-separated list of options.
Assume you'd like to override Coursier's memory settings:
COURSIER_OPTS="-Xms1g -Xmx4g"Try 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:
java.lang.NullPointerExceptionat java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)at java.base/java.lang.reflect.Field.get(Field.java:418)at org.robolectric.shadows.ShadowActivityThread$_ActivityThread_$$Reflector0.getActivities(Unknown Source)at org.robolectric.shadows.ShadowActivityThread.reset(ShadowActivityThread.java:277)at org.robolectric.Shadows.reset(Shadows.java:2499)at org.robolectric.android.internal.AndroidTestEnvironment.resetState(AndroidTestEnvironment.java:640)at org.robolectric.RobolectricTestRunner.lambda$finallyAfterTest$0(RobolectricTestRunner.java:361)at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:86)at org.robolectric.RobolectricTestRunner.finallyAfterTest(RobolectricTestRunner.java:359)at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:296)at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:99)at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)at java.base/java.lang.Thread.run(Thread.java:830)or
java.lang.UnsatisfiedLinkError: libstdc++.so.6: cannot open shared object file: No such file or directoryat java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2444)at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2500)at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2716)at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2629)at java.base/java.lang.Runtime.load0(Runtime.java:769)at java.base/java.lang.System.load(System.java:1840)at org.conscrypt.NativeLibraryUtil.loadLibrary(NativeLibraryUtil.java:52)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.base/java.lang.reflect.Method.invoke(Method.java:566) ...If you're writing a library that has dependencies, you should define a constant thatlists all of the artifacts that your library requires. For example:
# my_library/BUILD# Public interface of the libraryjava_library(name="my_interface",deps= ["@maven//:junit_junit","@maven//:com_google_inject_guice", ],)
# my_library/library_deps.bzl# All artifacts required by the libraryMY_LIBRARY_ARTIFACTS= ["junit:junit:4.12","com.google.inject:guice:4.0",]
Users of your library can then load the constant in theirWORKSPACE and add theartifacts to theirmaven_install. For example:
# user_project/WORKSPACEload("@my_library//:library_deps.bzl","MY_LIBRARY_ARTIFACTS")maven_install(artifacts= ["junit:junit:4.11","com.google.guava:guava:26.0-jre", ]+MY_LIBRARY_ARTIFACTS,)
# user_project/BUILDjava_library(name="user_lib",deps= ["@my_library//:my_interface","@maven//:junit_junit", ],)
Any version conflicts or duplicate artifacts will resolved automatically.
In order to publish an artifact from your repo to a maven repository, youmust first create ajava_export target. This is similar to a regularjava_library, but allows two additional parameters: the maven coordinatesand an optional template file to use for thepom.xml file.
# user_project/BUILDload("@rules_jvm_external//:defs.bzl","java_export")java_export(name="exported_lib",maven_coordinates="com.example:project:0.0.1",pom_template="pom.tmpl",# You can omit thissrcs=glob(["*.java"]),deps= ["//user_project/utils","@maven//:com_google_guava_guava", ],)
If you wish to publish an artifact with Kotlin source code to a maven repositoryyou can usekt_jvm_export. This rule has the same arguments and generatedrules asjava_export, but useskt_jvm_library instead ofjava_library.
# user_project/BUILDload("@rules_jvm_external//:kt_defs.bzl","kt_jvm_export")kt_jvm_export(name="exported_kt_lib",maven_coordinates="com.example:project:0.0.1",srcs=glob(["*.kt"]),)
In order to publish the artifact, usebazel run:
bazel run --define "maven_repo=file://$HOME/.m2/repository" //user_project:exported_lib.publish
Or, to publish to (eg) Sonatype's OSS repo:
bazelrun--stamp \--define"maven_repo=https://oss.sonatype.org/service/local/staging/deploy/maven2" \--define"maven_user=example_user" \--define"maven_password=hunter2" \--definegpg_sign=true \//user_project:exported_lib.publish`
Or, to publish to a Google Cloud Storage:
bazel run --define "maven_repo=gs://example-bucket/repository" //user_project:exported_lib.publish
Or, to publish to an Amazon S3 bucket:
bazel run --define "maven_repo=s3://example-bucket/repository" //user_project:exported_lib.publish
Or, to publish to a GCP Artifact Registry:
bazel run --define "maven_repo=artifactregistry://us-west1-maven.pkg.dev/project/repository" //user_project:exported_lib.publish
When using thegpg_sign option, the current default key will be used forsigning, and thegpg binary needs to be installed on the machine.
Certain 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:
Add:
startup --host_jvm_args=-Djava.net.preferIPv6Addresses=trueto your.bazelrcfile for Bazel's native downloader.-Djava.net.preferIPv6Addresses=true to theCOURSIER_OPTS` environment variable to provide JVM options for Coursier.
For more information, read theofficial docs for IPv6 support in Bazel.
You can find demos in theexamples/ directory.
Find other GitHub projects usingrules_jvm_externalwith this search query.
Set theRJE_VERBOSE environment variable totrue to printcoursier's verboseoutput. For example:
$ RJE_VERBOSE=true bazel run @unpinned_maven//:pinIn order to run tests, your system must have an Android SDK installed. You can install the Android SDK usingAndroid Studio, or through most system package managers.
$ bazel test //...The instructions for installing the Android SDK on macOS can be hardto find, but if you're comfortable usingHomeBrew,the following steps will install what you need and set up theANDROID_HOME environment variable that's required in order to runrules_jvm_external's own tests.
brew install android-commandlinetoolsexport ANDROID_HOME="$(brew --prefix)/share/android-commandlinetools"sdkmanager "build-tools;33.0.1" "cmdline-tools;latest" "ndk;25.1.8937393" "platform-tools" "platforms;android-33"You can add theexport ANDROID_HOME to your.zshrc or similarconfig file.
UseStardoc togenerate API documentation in thedocs directory usinggenerate_docs.sh.
Note that this script has a dependency on thedoctoc NPM package to automategenerating the table of contents. Install it withnpm -g i doctoc.
About
Bazel rules to resolve, fetch and export Maven artifacts
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Languages
- Starlark66.9%
- Java29.0%
- Shell3.5%
- Other0.6%