Add an allowlist for `java_import.exports`

PiperOrigin-RevId: 440117581
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java
index 18d7370..f7b1685 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java
@@ -104,6 +104,7 @@
   private final boolean experimentalEnableJspecify;
   private final boolean requireJavaPluginInfo;
   private final boolean multiReleaseDeployJars;
+  private final boolean disallowJavaImportExports;
 
   // TODO(dmarting): remove once we have a proper solution for #2539
   private final boolean useLegacyBazelJavaTest;
@@ -141,6 +142,7 @@
     this.limitAndroidLintToAndroidCompatible = javaOptions.limitAndroidLintToAndroidCompatible;
     this.requireJavaPluginInfo = javaOptions.requireJavaPluginInfo;
     this.multiReleaseDeployJars = javaOptions.multiReleaseDeployJars;
+    this.disallowJavaImportExports = javaOptions.disallowJavaImportExports;
 
     Map<String, Label> optimizers = javaOptions.bytecodeOptimizers;
     if (optimizers.size() > 1) {
@@ -347,6 +349,10 @@
     return multiReleaseDeployJars;
   }
 
+  public boolean disallowJavaImportExports() {
+    return disallowJavaImportExports;
+  }
+
   @Override
   public String starlarkOneVersionEnforcementLevel() {
     return oneVersionEnforcementLevel().name();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
index ebccff3..f8f90ad 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
@@ -56,6 +56,11 @@
       return null;
     }
 
+    if (exportError(ruleContext)) {
+      ruleContext.ruleError(
+          "java_import.exports is no longer supported; use java_import.deps instead");
+    }
+
     ImmutableList<TransitiveInfoCollection> targets =
         ImmutableList.<TransitiveInfoCollection>builder()
             .addAll(ruleContext.getPrerequisites("deps"))
@@ -188,6 +193,17 @@
     return isDirect ? provider.getDirectCompileTimeJars() : provider.getTransitiveCompileTimeJars();
   }
 
+  private static boolean exportError(RuleContext ruleContext) {
+    if (!ruleContext.attributes().isAttributeValueExplicitlySpecified("exports")) {
+      return false;
+    }
+    if (ruleContext.getFragment(JavaConfiguration.class).disallowJavaImportExports()) {
+      return true;
+    }
+    return Allowlist.hasAllowlist(ruleContext, "java_import_exports")
+        && !Allowlist.isAvailable(ruleContext, "java_import_exports");
+  }
+
   private NestedSet<Artifact> collectTransitiveJavaSourceJars(
       RuleContext ruleContext, Artifact srcJar) {
     NestedSetBuilder<Artifact> transitiveJavaSourceJarBuilder = NestedSetBuilder.stableOrder();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
index cc28a8e..1475c13 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
@@ -561,6 +561,15 @@
   public boolean multiReleaseDeployJars;
 
   @Option(
+      name = "incompatible_disallow_java_import_exports",
+      defaultValue = "false",
+      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+      effectTags = {OptionEffectTag.UNKNOWN},
+      metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE},
+      help = "When enabled, java_import.exports is not supported.")
+  public boolean disallowJavaImportExports;
+
+  @Option(
       name = "experimental_enable_jspecify",
       defaultValue = "true",
       documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
@@ -629,6 +638,8 @@
 
     host.multiReleaseDeployJars = multiReleaseDeployJars;
 
+    host.disallowJavaImportExports = disallowJavaImportExports;
+
     return host;
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/view/java/JavaImportConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/view/java/JavaImportConfiguredTargetTest.java
index f33783e..5d38681 100644
--- a/src/test/java/com/google/devtools/build/lib/view/java/JavaImportConfiguredTargetTest.java
+++ b/src/test/java/com/google/devtools/build/lib/view/java/JavaImportConfiguredTargetTest.java
@@ -59,6 +59,13 @@
         "java_import(name = 'libraryjar_with_srcjar',",
         "            jars = ['library.jar'],",
         "            srcjar = 'library.srcjar')");
+
+    scratch.overwriteFile(
+        "tools/allowlists/java_import_exports/BUILD",
+        "package_group(",
+        "    name = 'java_import_exports',",
+        "    packages = ['//...'],",
+        ")");
   }
 
   @Test
@@ -540,4 +547,17 @@
     assertThat(jars).doesNotContain("b-ijar.jar");
     assertThat(jars).contains("b.jar");
   }
+
+  @Test
+  public void testExports() throws Exception {
+    useConfiguration("--incompatible_disallow_java_import_exports");
+    checkError(
+        "ugly",
+        "jar",
+        "java_import.exports is no longer supported; use java_import.deps instead",
+        "java_library(name = 'dep', srcs = ['dep.java'])",
+        "java_import(name = 'jar',",
+        "    jars = ['dummy.jar'],",
+        "    exports = [':dep'])");
+  }
 }