Add java_common.build_ijar.

PiperOrigin-RevId: 167699728
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
index 358dd3c..b30ef83 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
@@ -344,11 +344,7 @@
         hostJavabaseProvider == null
             ? NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER)
             : hostJavabaseProvider.getMiddlemanArtifact();
-    JavaToolchainProvider javaToolchainProvider =
-        javaToolchain.getProvider(JavaToolchainProvider.class);
-    if (javaToolchain == null) {
-      throw new EvalException(null, javaToolchain.getLabel() + " is not a java_toolchain rule.");
-    }
+    JavaToolchainProvider javaToolchainProvider = getJavaToolchainProvider(javaToolchain);
     JavaCompilationArtifacts artifacts =
         helper.build(
             javaSemantics,
@@ -381,6 +377,40 @@
              .build();
   }
 
+  @SkylarkCallable(
+      name = "build_ijar",
+      documented = true,
+      doc = "Builds and returns the ijar file for the given jar file.",
+      mandatoryPositionals = 1,
+      parameters = {
+        @Param(
+          name = "jar",
+          positional = true,
+          named = true,
+          type = Artifact.class,
+          doc = "The input .jar file for which an ijar will be built. Mandatory."
+        ),
+        @Param(
+          name = "java_toolchain",
+          positional = true,
+          named = true,
+          type = ConfiguredTarget.class,
+          doc = "A label pointing to a java_toolchain rule to be used for this compilation. "
+            + "Mandatory."
+        ),
+      }
+  )
+  public Artifact buildIjar(
+      SkylarkRuleContext skylarkRuleContext,
+      Artifact fullJar,
+      ConfiguredTarget javaToolchain) throws EvalException {
+    return JavaCompilationHelper.createIjarAction(
+        skylarkRuleContext.getRuleContext(),
+        getJavaToolchainProvider(javaToolchain),
+        fullJar,
+        /* addPrefix = */ true);
+  }
+
   /**
    * Creates a {@link JavaSourceJarsProvider} from the given list of source jars.
    */
@@ -406,11 +436,7 @@
     RuleContext ruleContext = skylarkRuleContext.getRuleContext();
     ConfiguredTarget javaToolchainConfigTarget =
         (ConfiguredTarget) skylarkRuleContext.getAttr().getValue(javaToolchainAttr);
-    JavaToolchainProvider toolchain =
-        javaToolchainConfigTarget.getProvider(JavaToolchainProvider.class);
-    if (toolchain == null) {
-      throw new EvalException(null, javaToolchainAttr + " is not a java_toolchain rule label");
-    }
+    JavaToolchainProvider toolchain = getJavaToolchainProvider(javaToolchainConfigTarget);
     return ImmutableList.copyOf(Iterables.concat(
         toolchain.getJavacOptions(), ruleContext.getTokenizedStringListAttr("javacopts")));
   }
@@ -444,6 +470,16 @@
         .build();
   }
 
+  private static JavaToolchainProvider getJavaToolchainProvider(ConfiguredTarget javaToolchain)
+      throws EvalException{
+    JavaToolchainProvider javaToolchainProvider =
+        javaToolchain.getProvider(JavaToolchainProvider.class);
+    if (javaToolchainProvider == null) {
+      throw new EvalException(null, javaToolchain.getLabel() + " is not a java_toolchain rule.");
+    }
+    return javaToolchainProvider;
+  }
+
   /**
    * Returns a new JavaCompilationArgsProvider whose direct-jars part is the union of both the
    * direct and indirect jars of 'provider'.
diff --git a/src/test/shell/bazel/bazel_java_test.sh b/src/test/shell/bazel/bazel_java_test.sh
index de7aacc..db6fc54 100755
--- a/src/test/shell/bazel/bazel_java_test.sh
+++ b/src/test/shell/bazel/bazel_java_test.sh
@@ -1239,5 +1239,65 @@
   expect_log "Using type com.google.sandwich.C from an indirect dependency"
 }
 
+function test_java_common_build_ijar() {
+  mkdir -p java/com/google/foo
+  touch java/com/google/foo/{BUILD,A.java,my_rule.bzl}
+  cat > java/com/google/foo/A.java << EOF
+package com.google.foo;
+class A {}
+EOF
+  cat > java/com/google/foo/BUILD << EOF
+load(":my_rule.bzl", "my_rule")
+java_library(name = "a", srcs = ["A.java"])
+my_rule(name = "banana", jar = "liba.jar")
+EOF
+
+  cat > java/com/google/foo/my_rule.bzl << EOF
+def _impl(ctx):
+  ijar = java_common.build_ijar(ctx, ctx.files.jar[0], ctx.attr._java_toolchain)
+  print(ijar.path)
+  return DefaultInfo(files = depset([ijar]))
+
+my_rule = rule(
+  implementation = _impl,
+  attrs = {
+    "jar": attr.label(allow_files=True),
+    "_java_toolchain": attr.label(default = Label("@bazel_tools//tools/jdk:toolchain")),
+  }
+)
+EOF
+  bazel build java/com/google/foo:banana >& "$TEST_log" || fail "Unexpected fail"
+  expect_log "liba-ijar.jar"
+  unzip -l bazel-genfiles/java/com/google/foo/_ijar/banana/java/com/google/foo/liba-ijar.jar >> "$TEST_log"
+  expect_log "00:00   com/google/foo/A.class"
+}
+
+function test_java_common_create_empty_ijars() {
+  mkdir -p java/com/google/foo
+  touch java/com/google/foo/{BUILD,a.jar,my_rule.bzl}
+  cat > java/com/google/foo/BUILD << EOF
+load(":my_rule.bzl", "my_rule")
+exports_files(["a.jar"])
+my_rule(name = "banana", jar = "a.jar")
+EOF
+
+  cat > java/com/google/foo/my_rule.bzl << EOF
+def _impl(ctx):
+  ijar = java_common.build_ijar(ctx, ctx.files.jar[0], ctx.attr._java_toolchain)
+  print(ijar.path)
+  return DefaultInfo(files = depset([ijar]))
+
+my_rule = rule(
+  implementation = _impl,
+  attrs = {
+    "jar": attr.label(allow_files=True),
+    "_java_toolchain": attr.label(default = Label("@bazel_tools//tools/jdk:toolchain")),
+  }
+)
+EOF
+  bazel build java/com/google/foo:banana >& "$TEST_log" && fail "Unexpected success"
+  expect_log "Unable to open Zip file java/com/google/foo/a.jar: Invalid argument"
+}
+
 run_suite "Java integration tests"