java,runfiles: runfiles library in @bazel_tools

Also make most targets in `//src/tools/runfiles`
private. The user should depend on
`@bazel_tools//tools/runfiles:$LANG-runfiles`
instead.

See https://github.com/bazelbuild/bazel/issues/4460

RELNOTES[NEW]: java,runfiles: You can now depend on `@bazel_tools//tools/runfiles:java-runfiles` to get a platform-independent runfiles library for Java. See JavaDoc of https://github.com/bazelbuild/bazel/blob/master/src/tools/runfiles/java/com/google/devtools/build/runfiles/Runfiles.java for usage information.

Change-Id: Iba9113453222ae74ce42a324272711f613104891
PiperOrigin-RevId: 182022851
diff --git a/src/BUILD b/src/BUILD
index 119e19b..73d7aac 100644
--- a/src/BUILD
+++ b/src/BUILD
@@ -151,7 +151,7 @@
         "//src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper:srcs",
         "//src/tools/android/java/com/google/devtools/build/android:embedded_tools",
         "//src/tools/launcher:srcs",
-        "//src/tools/runfiles:srcs",
+        "//src/tools/runfiles:embedded_tools",
         "//src/tools/singlejar:embedded_tools",
         "//src/main/cpp/util:embedded_tools",
         "//src/main/native:embedded_tools",
diff --git a/src/test/py/bazel/runfiles_test.py b/src/test/py/bazel/runfiles_test.py
index 9d00c9b..da6a143 100644
--- a/src/test/py/bazel/runfiles_test.py
+++ b/src/test/py/bazel/runfiles_test.py
@@ -13,6 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import os
 import unittest
 from src.test.py.bazel import test_base
 
@@ -29,6 +30,55 @@
     self.assertIn("building runfiles is not supported on Windows",
                   "\n".join(stderr))
 
+  def testJavaRunfilesLibraryInBazelToolsRepo(self):
+    self.ScratchFile("WORKSPACE", ["workspace(name = 'foo_ws')"])
+    self.ScratchFile("foo/BUILD", [
+        "java_binary(",
+        "    name = 'Foo',",
+        "    main_class = 'Foo',",
+        "    srcs = ['Foo.java'],",
+        "    deps = ['@bazel_tools//tools/runfiles:java-runfiles'],",
+        "    data = ['//foo/bar:hello.txt'],",
+        ")"
+    ])
+    self.ScratchFile("foo/Foo.java", [
+        "import com.google.devtools.build.runfiles.Runfiles;",
+        ""
+        "public class Foo {",
+        "  public static void main(String[] args) throws java.io.IOException {",
+        "    System.out.println(\"Hello Foo!\");",
+        "    Runfiles r = Runfiles.create();",
+        "    System.out.println(",
+        "        \"rloc=\" + r.rlocation(\"foo_ws/foo/bar/hello.txt\"));",
+        "  }",
+        "}"
+    ])
+    self.ScratchFile("foo/bar/BUILD", ["exports_files(['hello.txt'])"])
+    self.ScratchFile("foo/bar/hello.txt", ["world"])
+
+    exit_code, stdout, stderr = self.RunBazel(["info", "bazel-bin"])
+    self.AssertExitCode(exit_code, 0, stderr)
+    bazel_bin = stdout[0]
+
+    exit_code, _, stderr = self.RunBazel(["build", "//foo:Foo"])
+    self.AssertExitCode(exit_code, 0, stderr)
+
+    bin_path = os.path.join(bazel_bin, "foo/Foo" +
+                            (".exe" if test_base.TestBase.IsWindows() else ""))
+    self.assertTrue(os.path.exists(bin_path))
+
+    exit_code, stdout, stderr = self.RunProgram([bin_path])
+    self.AssertExitCode(exit_code, 0, stderr)
+    if len(stdout) != 2:
+      self.fail("stdout: " + stdout)
+    self.assertEqual(stdout[0], "Hello Foo!")
+    self.assertRegexpMatches(stdout[1], "^rloc=.*/foo/bar/hello.txt")
+    with open(stdout[1].split("=", 1)[1], "r") as f:
+      lines = [l.strip() for l in f.readlines()]
+    if len(lines) != 1:
+      self.fail("lines: " + lines)
+    self.assertEqual(lines[0], "world")
+
 
 if __name__ == "__main__":
   unittest.main()
diff --git a/src/tools/runfiles/BUILD b/src/tools/runfiles/BUILD
index 3627e43..e0ba09f 100644
--- a/src/tools/runfiles/BUILD
+++ b/src/tools/runfiles/BUILD
@@ -1,9 +1,9 @@
-package(default_visibility = ["//visibility:private"])
+# This package contains sources for language-specific runfiles libraries.
+#
+# Do not depend on these rules. Depend on the ones in @bazel_tools//tools/runfiles instead, that way
+# your binary won't require the Bazel source tree to work correctly.
 
-exports_files(
-    ["runfiles.sh"],
-    visibility = ["//visibility:public"],
-)
+package(default_visibility = ["//visibility:private"])
 
 filegroup(
     name = "srcs",
@@ -16,10 +16,18 @@
     visibility = ["//src:__pkg__"],
 )
 
+filegroup(
+    name = "embedded_tools",
+    srcs = [
+        "BUILD.tools",
+        "//src/tools/runfiles/java/com/google/devtools/build/runfiles:embedded_tools",
+    ],
+    visibility = ["//src:__pkg__"],
+)
+
 sh_library(
     name = "runfiles_sh_lib",
     srcs = ["runfiles.sh"],
-    visibility = ["//visibility:public"],
 )
 
 sh_test(
@@ -31,12 +39,6 @@
     deps = [":runfiles_sh_lib"],
 )
 
-alias(
-    name = "java-runfiles",
-    actual = "//src/tools/runfiles/java/com/google/devtools/build/runfiles",
-    visibility = ["//visibility:public"],
-)
-
 test_suite(
     name = "windows_tests",
     tags = [
diff --git a/src/tools/runfiles/BUILD.tools b/src/tools/runfiles/BUILD.tools
new file mode 100644
index 0000000..d3244d9
--- /dev/null
+++ b/src/tools/runfiles/BUILD.tools
@@ -0,0 +1,4 @@
+# This package is intentionally not exporting anything.
+# This BUILD file's sole purpose is to declare a Bazel package.
+#
+# Use the targets in the @bazel_tools//tools/runfiles package instead.
diff --git a/src/tools/runfiles/java/com/google/devtools/build/runfiles/BUILD b/src/tools/runfiles/java/com/google/devtools/build/runfiles/BUILD
index 666c35f..e6d3d0b 100644
--- a/src/tools/runfiles/java/com/google/devtools/build/runfiles/BUILD
+++ b/src/tools/runfiles/java/com/google/devtools/build/runfiles/BUILD
@@ -19,6 +19,15 @@
     ],
 )
 
+filegroup(
+    name = "embedded_tools",
+    srcs = [
+        "BUILD.tools",
+        ":java-srcs",
+    ],
+    visibility = ["//src/tools/runfiles:__pkg__"],
+)
+
 java_library(
     name = "runfiles",
     srcs = [":java-srcs"],
diff --git a/src/tools/runfiles/java/com/google/devtools/build/runfiles/BUILD.tools b/src/tools/runfiles/java/com/google/devtools/build/runfiles/BUILD.tools
new file mode 100644
index 0000000..6a0bf08
--- /dev/null
+++ b/src/tools/runfiles/java/com/google/devtools/build/runfiles/BUILD.tools
@@ -0,0 +1,17 @@
+package(default_visibility = ["//visibility:private"])
+
+filegroup(
+    name = "java-srcs",
+    srcs = [
+        "DirectoryBased.java",
+        "ManifestBased.java",
+        "Runfiles.java",
+        "Util.java",
+    ],
+)
+
+java_library(
+    name = "runfiles",
+    srcs = [":java-srcs"],
+    visibility = ["//tools/runfiles:__pkg__"],
+)
diff --git a/tools/BUILD b/tools/BUILD
index a6d6ac3..24cae21 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -29,6 +29,7 @@
         "//tools/osx/crosstool:srcs",
         "//tools/test:srcs",
         "//tools/python:srcs",
+        "//tools/runfiles:srcs",
         "//tools/whitelists:srcs",
         "//tools/zip:srcs",
     ],
@@ -55,6 +56,7 @@
         "//tools/platforms:srcs",
         "//tools/objc:srcs",
         "//tools/python:srcs",
+        "//tools/runfiles:embedded_tools",
         "//tools/test:srcs",
         "//tools/osx/crosstool:srcs",
         "//tools/osx:srcs",
diff --git a/tools/runfiles/BUILD b/tools/runfiles/BUILD
new file mode 100644
index 0000000..7393367
--- /dev/null
+++ b/tools/runfiles/BUILD
@@ -0,0 +1,16 @@
+package(default_visibility = ["//visibility:private"])
+
+filegroup(
+    name = "srcs",
+    srcs = glob(
+        ["**"],
+        exclude = [".*"],  # .swp files and such
+    ),
+    visibility = ["//tools:__pkg__"],
+)
+
+filegroup(
+    name = "embedded_tools",
+    srcs = ["BUILD.tools"],
+    visibility = ["//tools:__pkg__"],
+)
diff --git a/tools/runfiles/BUILD.tools b/tools/runfiles/BUILD.tools
new file mode 100644
index 0000000..d928523
--- /dev/null
+++ b/tools/runfiles/BUILD.tools
@@ -0,0 +1,6 @@
+package(default_visibility = ["//visibility:public"])
+
+alias(
+    name = "java-runfiles",
+    actual = "//src/tools/runfiles/java/com/google/devtools/build/runfiles",
+)