Bazel powered Java testing (#8506)

* Protobuf Java/Core Tests running w/ Bazel.

Also integrates rules_jvm_external and migrates existing maven deps
in place.

* Add test_suite target that maps to rule name.

* Lite tests passing in Bazel

* util tests passing with Bazel.

* Add conformance and build testing to //java:core

* Cleanup bzl style and lock down access to failure lists.

* Adding Java Lite conformance tests.

* rm newline

* parameterize conformance_test

This makes usage of failure lists more explicit.

* restrict visibility more for newly added libs and fix formatting.

* fix formatting and visibility.

* move testing.bzl to an internal package.

* fix file formatting.

* moving conformance_test to internal.bzl
diff --git a/java/BUILD b/java/BUILD
new file mode 100644
index 0000000..8778bf9
--- /dev/null
+++ b/java/BUILD
@@ -0,0 +1,8 @@
+test_suite(
+  name = "tests",
+  tests = [
+    "//java/core:tests",
+    "//java/lite:tests",
+    "//java/util:tests",
+  ],
+)
diff --git a/java/core/BUILD b/java/core/BUILD
index fa074c0..4d8895a 100644
--- a/java/core/BUILD
+++ b/java/core/BUILD
@@ -1,5 +1,8 @@
-load("@rules_java//java:defs.bzl", "java_library")
-load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain")
+load("@bazel_skylib//rules:build_test.bzl", "build_test")
+load("@rules_java//java:defs.bzl", "java_library", "java_proto_library", "java_lite_proto_library")
+load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library")
+load("//:internal.bzl", "conformance_test")
+load("//java/internal:testing.bzl", "junit_tests")
 
 LITE_SRCS = [
     # Keep in sync with `//java/lite:pom.xml`.
@@ -95,13 +98,20 @@
 # Should be used as `//java/lite`.
 java_library(
     name = "lite",
-    srcs = LITE_SRCS,
+    srcs = LITE_SRCS + [
+        "//:gen_well_known_protos_javalite"
+    ],
     visibility = [
         "//java/lite:__pkg__",
     ],
 )
 
 java_library(
+    name = "lite_runtime_only",
+    srcs = LITE_SRCS,
+)
+
+java_library(
     name = "core",
     srcs = glob(
         [
@@ -113,10 +123,10 @@
     ],
     visibility = ["//visibility:public"],
     exports = [
-        "//java/lite",
+        ":lite_runtime_only",
     ],
     deps = [
-        "//java/lite",
+        ":lite_runtime_only",
     ],
 )
 
@@ -126,3 +136,191 @@
     runtime = ":core",
     visibility = ["//visibility:public"],
 )
+
+proto_library(
+    name = "java_test_protos",
+    srcs = glob(["src/test/proto/**/*.proto"]),
+    strip_import_prefix = "src/test/proto",
+    deps = [
+        "//:any_proto",
+        "//:descriptor_proto",
+        "//:generic_test_protos",
+        "//:wrappers_proto",
+    ],
+)
+
+java_proto_library(
+    name = "generic_test_protos_java_proto",
+    visibility = [
+        "//java:__subpackages__",
+    ],
+    deps = ["//:generic_test_protos"],
+)
+
+java_proto_library(
+    name = "java_test_protos_java_proto",
+    deps = [":java_test_protos"],
+)
+
+java_library(
+    name = "test_util",
+    srcs = [
+        "src/test/java/com/google/protobuf/TestUtil.java",
+        "src/test/java/com/google/protobuf/TestUtilLite.java"
+    ],
+    deps = [
+        ":core",
+        ":generic_test_protos_java_proto",
+        ":java_test_protos_java_proto",
+        "//external:guava",
+        "//external:junit",
+    ],
+)
+
+test_suite(
+    name = "tests",
+    tests = [
+        "core_build_test",
+        "conformance_test",
+        "core_tests",
+    ],
+)
+
+build_test(
+    name = "core_build_test",
+    targets = [
+        ":core",
+    ],
+)
+
+conformance_test(
+    name = "conformance_test",
+    testee = "//:conformance_java",
+    failure_list = "//:conformance/failure_list_java.txt",
+    text_format_failure_list = "//:conformance/text_format_failure_list_java.txt",
+)
+
+junit_tests(
+    name = "core_tests",
+    srcs = glob(["src/test/java/**/*.java"], exclude = [
+        "src/test/java/com/google/protobuf/TestUtil.java",
+        "src/test/java/com/google/protobuf/TestUtilLite.java",
+    ]),
+    data = ["//:testdata"],
+    size = "large",
+    deps = [
+        ":core",
+        ":generic_test_protos_java_proto",
+        ":java_test_protos_java_proto",
+        ":test_util",
+        "//external:easymock",
+        "//external:easymock_classextension",
+        "//external:junit",
+        "//external:truth",
+    ]
+)
+
+java_lite_proto_library(
+    name = "generic_test_protos_java_proto_lite",
+    visibility = [
+        "//java/lite:__pkg__",
+    ],
+    deps = ["//:generic_test_protos"],
+)
+
+java_lite_proto_library(
+    name = "java_test_protos_java_proto_lite",
+    visibility = [
+        "//java/lite:__pkg__",
+    ],
+    deps = [":java_test_protos"],
+)
+
+genrule(
+    name = "rewrite_javalite_test_util",
+    srcs = [
+        "//java/lite:lite.awk",
+        "src/test/java/com/google/protobuf/TestUtil.java"
+    ],
+    outs = ["TestUtil.java"],
+    cmd = "awk -f $(location //java/lite:lite.awk) $(location src/test/java/com/google/protobuf/TestUtil.java) > $@"
+)
+
+java_library(
+    name = "test_util_lite",
+    srcs = [
+        ":rewrite_javalite_test_util",
+        "src/test/java/com/google/protobuf/TestUtilLite.java"
+    ],
+    visibility = [
+        "//java/lite:__pkg__",
+    ],
+    deps = [
+        ":generic_test_protos_java_proto_lite",
+        ":java_test_protos_java_proto_lite",
+        ":lite_runtime_only",
+        "//external:guava",
+        "//external:junit",
+    ],
+)
+
+LITE_TEST_EXCLUSIONS = [
+    # Keep in sync with //java/lite:pom.xml id=copy-test-source-files execution.
+    "src/test/java/com/google/protobuf/AbstractMessageTest.java",
+    "src/test/java/com/google/protobuf/AbstractProto2SchemaTest.java",
+    "src/test/java/com/google/protobuf/AnyTest.java",
+    "src/test/java/com/google/protobuf/CodedInputStreamTest.java",
+    "src/test/java/com/google/protobuf/DeprecatedFieldTest.java",
+    "src/test/java/com/google/protobuf/DescriptorsTest.java",
+    "src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java",
+    "src/test/java/com/google/protobuf/DynamicMessageTest.java",
+    "src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java",
+    "src/test/java/com/google/protobuf/FieldPresenceTest.java",
+    "src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java",
+    "src/test/java/com/google/protobuf/GeneratedMessageTest.java",
+    "src/test/java/com/google/protobuf/LazyFieldTest.java",
+    "src/test/java/com/google/protobuf/LazyStringEndToEndTest.java",
+    "src/test/java/com/google/protobuf/MapForProto2Test.java",
+    "src/test/java/com/google/protobuf/MapTest.java",
+    "src/test/java/com/google/protobuf/MessageTest.java",
+    "src/test/java/com/google/protobuf/NestedBuildersTest.java",
+    "src/test/java/com/google/protobuf/PackedFieldTest.java",
+    "src/test/java/com/google/protobuf/ParserTest.java",
+    "src/test/java/com/google/protobuf/ParseExceptionsTest.java",
+    "src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java",
+    "src/test/java/com/google/protobuf/Proto2SchemaTest.java",
+    "src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java",
+    "src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java",
+    "src/test/java/com/google/protobuf/ServiceTest.java",
+    "src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java",
+    "src/test/java/com/google/protobuf/TestBadIdentifiers.java",
+    "src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java",
+    "src/test/java/com/google/protobuf/TextFormatParseLocationTest.java",
+    "src/test/java/com/google/protobuf/TextFormatTest.java",
+    "src/test/java/com/google/protobuf/TestUtil.java",
+    "src/test/java/com/google/protobuf/TestUtilLite.java",
+    "src/test/java/com/google/protobuf/TypeRegistryTest.java",
+    "src/test/java/com/google/protobuf/UnknownEnumValueTest.java",
+    "src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java",
+    "src/test/java/com/google/protobuf/UnknownFieldSetTest.java",
+    "src/test/java/com/google/protobuf/WellKnownTypesTest.java",
+    "src/test/java/com/google/protobuf/WireFormatTest.java",
+]
+
+junit_tests(
+    name = "lite_tests",
+    srcs = glob(["src/test/java/**/*.java"], exclude = LITE_TEST_EXCLUSIONS),
+    data = ["//:testdata"],
+    test_prefix = "Lite",
+    size = "large",
+    deps = [
+        ":lite",
+        ":generic_test_protos_java_proto_lite",
+        ":java_test_protos_java_proto_lite",
+        ":test_util_lite",
+        "//external:easymock",
+        "//external:easymock_classextension",
+        "//external:junit",
+        "//external:truth",
+    ]
+)
diff --git a/java/internal/BUILD b/java/internal/BUILD
new file mode 100644
index 0000000..4f542ec
--- /dev/null
+++ b/java/internal/BUILD
@@ -0,0 +1 @@
+package(default_visibility = ["//java:__subpackages__"])
\ No newline at end of file
diff --git a/java/internal/testing.bzl b/java/internal/testing.bzl
new file mode 100644
index 0000000..76e1e45
--- /dev/null
+++ b/java/internal/testing.bzl
@@ -0,0 +1,72 @@
+"""
+Generates a side-car JUnit suite test runner class for each
+input src.
+"""
+_template = """import org.junit.runners.Suite;
+import org.junit.runner.RunWith;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({%s})
+public class %s {}
+"""
+
+def _as_classname(fname, pkg):
+    path_name = [x.path for x in fname.files.to_list()][0]
+    file_name = path_name.split("/")[-1]
+    return ".".join([pkg, file_name.split(".")[0]]) + ".class"
+
+def _gen_suite_impl(ctx):
+    classes = ",".join(
+        [_as_classname(x, ctx.attr.package_name) for x in ctx.attr.srcs],
+    )
+    ctx.actions.write(output = ctx.outputs.out, content = _template % (
+        classes,
+        ctx.attr.outname,
+    ))
+
+_gen_suite = rule(
+    attrs = {
+        "srcs": attr.label_list(allow_files = True),
+        "package_name": attr.string(),
+        "outname": attr.string(),
+    },
+    outputs = {"out": "%{name}.java"},
+    implementation = _gen_suite_impl,
+)
+
+def junit_tests(name, srcs, data = [], deps = [], package_name = "com.google.protobuf", test_prefix = None, **kwargs):
+    testlib_name = "%s_lib" % name
+    native.java_library(
+        name = testlib_name,
+        srcs = srcs,
+        deps = deps,
+        resources = data,
+        data = data,
+    )
+    test_names = []
+    prefix = name.replace("-", "_") + "TestSuite"
+    for src in srcs:
+        test_name = src.rsplit("/", 1)[1].split(".")[0]
+        if not test_name.endswith("Test") or test_name.startswith("Abstract"):
+            continue
+        if test_prefix:
+            test_name = "%s%s" % (test_prefix, test_name)  
+        test_names = test_names + [test_name]
+        suite_name = prefix + '_' + test_name
+        _gen_suite(
+            name = suite_name,
+            srcs = [src],
+            package_name = package_name,
+            outname = suite_name,
+        )
+        native.java_test(
+            name = test_name,
+            test_class = suite_name,
+            srcs = [src] + [":" + suite_name],
+            deps = deps + [":%s" % testlib_name],
+            **kwargs
+        )
+    native.test_suite(
+        name = name,
+        tests = test_names,
+    )
diff --git a/java/lite/BUILD b/java/lite/BUILD
index 22840ec..639f308 100644
--- a/java/lite/BUILD
+++ b/java/lite/BUILD
@@ -1,4 +1,9 @@
+load("@bazel_skylib//rules:build_test.bzl", "build_test")
 load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain")
+load("//:internal.bzl", "conformance_test")
+load("//java/internal:testing.bzl", "junit_tests")
+
+exports_files(["lite.awk"], visibility = ["//java/core:__pkg__"])
 
 alias(
     name = "lite",
@@ -12,3 +17,40 @@
     runtime = ":lite",
     visibility = ["//visibility:public"],
 )
+
+test_suite(
+    name = "tests",
+    tests = [
+        "lite_build_test",
+        "conformance_test",
+        "lite_tests",
+        "//java/core:lite_tests",
+    ],
+)
+
+build_test(
+    name = "lite_build_test",
+    targets = [
+        ":lite",
+    ],
+)
+
+conformance_test(
+    name = "conformance_test",
+    testee = "//:conformance_java_lite",
+    failure_list = "//:conformance/failure_list_java_lite.txt",
+    text_format_failure_list = "//:conformance/text_format_failure_list_java_lite.txt",
+)
+
+junit_tests(
+    name = "lite_tests",
+    srcs = glob(["src/test/**/*.java"]),
+    size = "small",
+    deps = [
+        ":lite",
+        "//external:junit",
+        "//java/core:generic_test_protos_java_proto_lite",
+        "//java/core:java_test_protos_java_proto_lite",
+        "//java/core:test_util_lite",
+    ],
+)
diff --git a/java/lite/pom.xml b/java/lite/pom.xml
index 5f03845..cd1a3eb 100644
--- a/java/lite/pom.xml
+++ b/java/lite/pom.xml
@@ -199,6 +199,7 @@
                   and exclude only the full runtime exclusive tests so we don't accidentally miss
                   any test. -->
                   <excludes>
+                    <!-- Keep in sync with //java/core:lite_tests BUILD rule. -->
                     <exclude>AbstractMessageTest.java</exclude>
                     <exclude>AbstractProto2SchemaTest.java</exclude>
                     <exclude>AnyTest.java</exclude>
diff --git a/java/util/BUILD b/java/util/BUILD
index 71f73ba..25853f7 100644
--- a/java/util/BUILD
+++ b/java/util/BUILD
@@ -1,4 +1,6 @@
-load("@rules_java//java:defs.bzl", "java_library")
+load("@rules_java//java:defs.bzl", "java_library", "java_proto_library")
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("//java/internal:testing.bzl", "junit_tests")
 
 java_library(
     name = "util",
@@ -14,3 +16,36 @@
         "//java/lite",
     ],
 )
+
+proto_library(
+    name = "test_protos",
+    srcs = glob(["src/test/proto/**/*.proto"]),
+    deps = [
+        "//:any_proto",
+        "//:duration_proto",
+        "//:field_mask_proto",
+        "//:struct_proto",
+        "//:timestamp_proto",
+        "//:wrappers_proto",
+    ],
+)
+
+java_proto_library(
+    name = "test_protos_java_proto",
+    deps = [":test_protos"],
+)
+
+junit_tests(
+    name = "tests",
+    srcs = glob(["src/test/java/**/*.java"]),
+    package_name = "com.google.protobuf.util",
+    deps = [
+        ":test_protos_java_proto",
+        ":util",
+        "//external:guava",
+        "//external:junit",
+        "//external:truth",
+        "//java/core",
+        "//java/core:generic_test_protos_java_proto",
+    ],
+)