Fix the `alias` generated when using `bzlmod` and the `maven` resolver (#1249)

This always assumed that the repo with the default name was visible
but what we actually need is the canonical repo name.
diff --git a/BUILD b/BUILD
index 9bb85b6..770e6d7 100644
--- a/BUILD
+++ b/BUILD
@@ -12,6 +12,7 @@
     srcs = [
         ":defs.bzl",
         ":specs.bzl",
+        "@bazel_features//:bzl_files",
         "@rules_license//:docs_deps",
     ],
     visibility = [
diff --git a/examples/bzlmod/BUILD b/examples/bzlmod/BUILD
index e69de29..5dee0ee 100644
--- a/examples/bzlmod/BUILD
+++ b/examples/bzlmod/BUILD
@@ -0,0 +1,11 @@
+load("@rules_jvm_external//:defs.bzl", "artifact")
+
+# You can load artifacts from different `maven.install` tags by using the
+# `repository_name` parameter of the `artifact` macro.
+alias(
+    name = "junit-api",
+    actual = artifact(
+        "org.junit.jupiter:junit-jupiter-api",
+        repository_name = "alternative_resolver",
+    ),
+)
diff --git a/examples/bzlmod/MODULE.bazel b/examples/bzlmod/MODULE.bazel
index 150ed0c..258e0b9 100644
--- a/examples/bzlmod/MODULE.bazel
+++ b/examples/bzlmod/MODULE.bazel
@@ -3,7 +3,7 @@
     version = "6.0",
 )
 
-bazel_dep(name = "rules_jvm_external", version = "6.0")
+bazel_dep(name = "rules_jvm_external", version = "0.0")
 local_path_override(
     module_name = "rules_jvm_external",  # matches the name of the `bazel_dep`
     path = "../..",
@@ -23,8 +23,20 @@
     fetch_sources = True,
     lock_file = "//:maven_install.json",
 )
-use_repo(
-    maven,
-    "maven",
-    "unpinned_maven",
+
+# The default resolver cannot handle Maven BOMs, but the `maven`
+# resolver can. Demonstrate how to use it.
+maven.install(
+    name = "alternative_resolver",
+    artifacts = [
+        "org.junit.jupiter:junit-jupiter-api",
+    ],
+    boms = [
+        "org.junit:junit-bom:5.11.0",
+    ],
+    # Before the first pin, this file was completely empty. Running:
+    # `REPIN=1 bazel run @alternative_resolver//:pin` generated it.
+    lock_file = "//:alternative_maven_install.json",
+    resolver = "maven",
 )
+use_repo(maven, "alternative_resolver", "maven")
diff --git a/examples/bzlmod/alternative_maven_install.json b/examples/bzlmod/alternative_maven_install.json
new file mode 100644
index 0000000..8d37065
--- /dev/null
+++ b/examples/bzlmod/alternative_maven_install.json
@@ -0,0 +1,78 @@
+{
+  "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
+  "__INPUT_ARTIFACTS_HASH": 126045399,
+  "__RESOLVED_ARTIFACTS_HASH": 246607592,
+  "artifacts": {
+    "org.apiguardian:apiguardian-api": {
+      "shasums": {
+        "jar": "b509448ac506d607319f182537f0b35d71007582ec741832a1f111e5b5b70b38"
+      },
+      "version": "1.1.2"
+    },
+    "org.junit.jupiter:junit-jupiter-api": {
+      "shasums": {
+        "jar": "42aa202fc862f76cc5af65b47b1c0b1961cdd79cd2216405a6dfa2bd20b20974"
+      },
+      "version": "5.11.0"
+    },
+    "org.junit.platform:junit-platform-commons": {
+      "shasums": {
+        "jar": "609333a4545f9018eb0c59071efd30663a9e9fdce528121b65a04c27e5fc26a7"
+      },
+      "version": "1.11.0"
+    },
+    "org.opentest4j:opentest4j": {
+      "shasums": {
+        "jar": "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b"
+      },
+      "version": "1.3.0"
+    }
+  },
+  "dependencies": {
+    "org.junit.jupiter:junit-jupiter-api": [
+      "org.apiguardian:apiguardian-api",
+      "org.junit.platform:junit-platform-commons",
+      "org.opentest4j:opentest4j"
+    ],
+    "org.junit.platform:junit-platform-commons": [
+      "org.apiguardian:apiguardian-api"
+    ]
+  },
+  "packages": {
+    "org.apiguardian:apiguardian-api": [
+      "org.apiguardian.api"
+    ],
+    "org.junit.jupiter:junit-jupiter-api": [
+      "org.junit.jupiter.api",
+      "org.junit.jupiter.api.condition",
+      "org.junit.jupiter.api.extension",
+      "org.junit.jupiter.api.extension.support",
+      "org.junit.jupiter.api.function",
+      "org.junit.jupiter.api.io",
+      "org.junit.jupiter.api.parallel"
+    ],
+    "org.junit.platform:junit-platform-commons": [
+      "org.junit.platform.commons",
+      "org.junit.platform.commons.annotation",
+      "org.junit.platform.commons.function",
+      "org.junit.platform.commons.logging",
+      "org.junit.platform.commons.support",
+      "org.junit.platform.commons.support.conversion",
+      "org.junit.platform.commons.util"
+    ],
+    "org.opentest4j:opentest4j": [
+      "org.opentest4j"
+    ]
+  },
+  "repositories": {
+    "https://repo1.maven.org/maven2/": [
+      "org.apiguardian:apiguardian-api",
+      "org.junit.jupiter:junit-jupiter-api",
+      "org.junit.platform:junit-platform-commons",
+      "org.opentest4j:opentest4j"
+    ]
+  },
+  "services": {},
+  "skipped": [],
+  "version": "2"
+}
diff --git a/private/extensions/maven.bzl b/private/extensions/maven.bzl
index cbe6389..cbe4064 100644
--- a/private/extensions/maven.bzl
+++ b/private/extensions/maven.bzl
@@ -434,10 +434,12 @@
                 additional_coursier_options = repo.get("additional_coursier_options"),
             )
         else:
+            workspace_prefix = "@@" if bazel_features.external_deps.is_bzlmod_enabled else "@"
+
             # Only the coursier resolver allows the lock file to be omitted.
             unpinned_maven_pin_command_alias(
                 name = "unpinned_" + name,
-                alias = "@%s//:pin" % name,
+                alias = "%s%s//:pin" % (workspace_prefix, name),
             )
 
         if repo.get("generate_compat_repositories") and not repo.get("lock_file"):
diff --git a/private/rules/maven_bom.bzl b/private/rules/maven_bom.bzl
index 906c68c..f391ab5 100644
--- a/private/rules/maven_bom.bzl
+++ b/private/rules/maven_bom.bzl
@@ -1,23 +1,14 @@
+load("@bazel_features//:features.bzl", "bazel_features")
 load("//private/lib:coordinates.bzl", "unpack_coordinates")
 load(":maven_bom_fragment.bzl", "MavenBomFragmentInfo")
 load(":maven_publish.bzl", "maven_publish")
 load(":maven_utils.bzl", "generate_pom")
 
-_NON_EXISTENT_LABEL = Label("//:thisdoesnotexistinrulesjvmexternal")
-
-def _is_using_bzlmod():
-    # There's no easy way in a macro to tell if you're using bzlmod. We can't
-    # depend on Bazel version number because `--noenable_bzlmod` may have been
-    # used. Instead, try and stringify a label we know doesn't exist. When
-    # bzlmod is in play, we'll get `[unknown repo` in the value. When it is not
-    # we get the label as we expect it to be.
-    return str(_NON_EXISTENT_LABEL).startswith("@@")
-
 def _label(label_or_string):
     if type(label_or_string) == "Label":
         return label_or_string
 
-    workspace_prefix = "@@" if _is_using_bzlmod() else "@"
+    workspace_prefix = "@@" if bazel_features.external_deps.is_bzlmod_enabled else "@"
 
     if type(label_or_string) == "string":
         # We may have a target of the form: `@bar//foo`, `//foo`, `//foo:foo`, `:foo`, `foo`
@@ -179,13 +170,9 @@
 
     # `same_package_label` doesn't exist in Bazel 5, but we still support it
     # so we check the version here to call a non-deprecated API in recent
-    # Bazel versions, or the older (deprecated) API in Bazel 5. Now, normally
-    # we'd use Skylib's `version` but that needs `native.bazel_version` to be
-    # present, and that's not available to macros. Instead, see whether what
-    # we need is present. Pulling in `bazel_features` for this check seems like
-    # overkill, especially since we'd need to land a patch in it before we
-    # could check this feature. Doing this the Not Invented Here way for now.
-    if "same_package_label" in dir(_NON_EXISTENT_LABEL):
+    # Bazel versions, or the older (deprecated) API in Bazel 5.
+    feature_check_label = Label("//:doesnotexistinrulesjvmexternal")
+    if hasattr(feature_check_label, "same_package_label"):
         fragments = [l.same_package_label("%s.bom-fragment" % l.name) for l in labels]
     else:
         # TODO: Drop this branch once we drop Bazel 5 support
diff --git a/repositories.bzl b/repositories.bzl
index 4aae636..a70725a 100644
--- a/repositories.bzl
+++ b/repositories.bzl
@@ -57,6 +57,14 @@
         sha256 = "26d4021f6898e23b82ef953078389dd49ac2b5618ac564ade4ef87cced147b38",
     )
 
+    maybe(
+        http_archive,
+        name = "bazel_features",
+        sha256 = "bdc12fcbe6076180d835c9dd5b3685d509966191760a0eb10b276025fcb76158",
+        strip_prefix = "bazel_features-1.17.0",
+        url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.17.0/bazel_features-v1.17.0.tar.gz",
+    )
+
     maven_install(
         name = "rules_jvm_external_deps",
         artifacts = [
diff --git a/setup.bzl b/setup.bzl
index 6996148..8942c58 100644
--- a/setup.bzl
+++ b/setup.bzl
@@ -1,3 +1,4 @@
+load("@bazel_features//:deps.bzl", "bazel_features_deps")
 load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
 load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
 load("@rules_jvm_external_deps//:defs.bzl", "pinned_maven_install")
@@ -5,6 +6,8 @@
 def rules_jvm_external_setup():
     bazel_skylib_workspace()
 
+    bazel_features_deps()
+
     # When using bazel 5, we have undefined toolchains from rules_js. This should be fine to skip, since we only need
     # it for the `JavaInfo` definition.
     major_version = native.bazel_version.partition(".")[0]