Skip to content

j2cl_test breaks when classpath contains package named "java" #290

@DragonAxe

Description

@DragonAxe

Describe the bug
The j2cl_test rule has logic to automatically find the java package name for use in the generated files. The package name is found by finding the closest parent folder who's name equals "java" (See the function here get_java_package in j2cl_util. The logic works fine for most cases, but not when the classpath contains a java package named "java".

For example, a test class path of com.acme.java.extensions (path src/test/java/com/acme/java/extensions) will not compile because j2cl_test stops too soon at the first "java" resulting in the generated files starting at src/test/java/com/acme/java instead of src/test/java like I would expect.

I can set j2cl_test's test_class parameter which fixes the class name used in the @J2clTestInput annotation (without test_class parameter: @J2clTestInput(.HelloWorldTest.class)), but then I run into the error shown in the output below.

To Reproduce

  • Start with the examples/helloworld project.
  • Rename the folder helloworldlib to java:
    samples/helloworld/src/test/java/com/google/j2cl/samples/helloworldlib
    to
    samples/helloworld/src/test/java/com/google/j2cl/samples/java
  • Edit samples/helloworld/src/test/java/com/google/j2cl/samples/java/BUILD to set the test_class parameter manually:
load("@j2cl//build_defs:rules.bzl", "j2cl_test")

package(
    default_applicable_licenses = ["@j2cl//:j2cl_license"],
    licenses = ["notice"],
)

j2cl_test(
    name = "HelloWorldTest",
    srcs = glob(["*.java"]),
    test_class = "com.google.j2cl.samples.java.HelloWorldTest",  # Add this line to force correct class name used in the generated suite file.
    deps = [
        "//src/main/java/com/google/j2cl/samples/helloworldlib",
        "@j2cl//:junit",
    ],
)
  • Run bazel build //src/test/java/com/google/j2cl/samples/java:HelloWorldTest
❯ bazel build //src/test/java/com/google/j2cl/samples/java:HelloWorldTest --verbose_failures
DEBUG: Rule 'j2cl+' indicated that a canonical reproducible form can be obtained by modifying arguments commit = "b22267f8fc5e73f0d4cac5994f11077a2120da58" and dropping ["tag"]
DEBUG: Repository j2cl+ instantiated at:
  <builtin>: in <toplevel>
Repository rule git_repository defined at:
  /home/user/.cache/bazel/_bazel_user/41a9ab5b7375ca59d673203c7a70444b/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
WARNING: /home/user/.cache/bazel/_bazel_user/41a9ab5b7375ca59d673203c7a70444b/external/rules_closure+/java/com/google/javascript/jscomp/BUILD:19:13: in java_library rule @@rules_closure+//java/com/google/javascript/jscomp:jscomp: target '@@rules_closure+//java/com/google/javascript/jscomp:jscomp' depends on deprecated target '@@rules_closure+//java/io/bazel/rules/closure:build_info_java_proto': Use java_proto_library from @com_google_protobuf//bazel:java_proto_library.bzl
INFO: Analyzed target //src/test/java/com/google/j2cl/samples/java:HelloWorldTest (270 packages loaded, 8155 targets configured).
INFO: Multiplexer process for Javac has closed its output stream
ERROR: /home/user/a/prog/2026-j2cl/j2cl/samples/helloworld/src/test/java/com/google/j2cl/samples/java/BUILD:8:10: Building src/test/java/com/google/j2cl/samples/java/libHelloWorldTest_generated_suite_lib.jar (1 source jar) and running annotation processors (J2clTestingProcessor) failed: (Exit 1): java failed: error executing Javac command (from target //src/test/java/com/google/j2cl/samples/java:HelloWorldTest_generated_suite_lib) 
  (cd /home/user/.cache/bazel/_bazel_user/41a9ab5b7375ca59d673203c7a70444b/execroot/_main && \
  exec env - \
    LC_CTYPE=C.UTF-8 \
    PATH=/home/user/.cache/bazelisk/downloads/sha256/17247e8a84245f59d3bc633d0cfe0a840992a7760a11af1a30012d03da31604c/bin:/home/user/.pyenv/shims:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/var/lib/flatpak/exports/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin:/home/user/.local/share/JetBrains/Toolbox/scripts \
  external/rules_java++toolchains+remotejdk21_linux/bin/java '--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.resources=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED' '--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED' '--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED' '--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED' '--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED' '--add-opens=java.base/java.nio=ALL-UNNAMED' '--add-opens=java.base/java.lang=ALL-UNNAMED' '-Dsun.io.useCanonCaches=false' -XX:-CompactStrings -Xlog:disable '-Xlog:all=warning:stderr:uptime,level,tags' -jar external/rules_java++toolchains+remote_java_tools/java_tools/JavaBuilder_deploy.jar @bazel-out/k8-fastbuild/bin/src/test/java/com/google/j2cl/samples/java/libHelloWorldTest_generated_suite_lib.jar-0.params @bazel-out/k8-fastbuild/bin/src/test/java/com/google/j2cl/samples/java/libHelloWorldTest_generated_suite_lib.jar-1.params)
# Configuration: d4c5211d3491ee25bd7b54263a1e1a8b876173641d0da1bff9b2c3ffd34d12a4
# Execution platform: @@platforms//host:host
bazel-out/k8-fastbuild/bin/src/test/java/com/google/j2cl/samples/java/_javac/HelloWorldTest_generated_suite_lib/libHelloWorldTest_generated_suite_lib_tmp/bazel-out/k8-fastbuild/bin/src/test/java/com/google/j2cl/samples/java/Helloworldtest_Generated_SuiteJ2clTestInput.java:14: error: cannot find symbol
@J2clTestInput(com.google.j2cl.samples.java.HelloWorldTest.class)
                                           ^
  symbol:   class HelloWorldTest
  location: package com.google.j2cl.samples.java
error: Test class is not found. Ensure that test_class is a fully qualified class name and exists in the classpath.
bazel-out/k8-fastbuild/bin/src/test/java/com/google/j2cl/samples/java/_javac/HelloWorldTest_generated_suite_lib/libHelloWorldTest_generated_suite_lib_tmp/bazel-out/k8-fastbuild/bin/src/test/java/com/google/j2cl/samples/java/Helloworldtest_Generated_SuiteJ2clTestInput.java:15: error: [J2clTestingProcessor:MiscError] com.google.j2cl.junit.apt.J2clTestingProcessor was unable to process this class because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.
public class Helloworldtest_Generated_SuiteJ2clTestInput {}
       ^
Target //src/test/java/com/google/j2cl/samples/java:HelloWorldTest failed to build
ERROR: /home/user/a/prog/2026-j2cl/j2cl/samples/helloworld/src/test/java/com/google/j2cl/samples/java/BUILD:8:10 Middleman _middlemen/src_Stest_Sjava_Scom_Sgoogle_Sj2cl_Ssamples_Sjava_SHelloWorldTest-runfiles failed: (Exit 1): java failed: error executing Javac command (from target //src/test/java/com/google/j2cl/samples/java:HelloWorldTest_generated_suite_lib) 
  (cd /home/user/.cache/bazel/_bazel_user/41a9ab5b7375ca59d673203c7a70444b/execroot/_main && \
  exec env - \
    LC_CTYPE=C.UTF-8 \
    PATH=/home/user/.cache/bazelisk/downloads/sha256/17247e8a84245f59d3bc633d0cfe0a840992a7760a11af1a30012d03da31604c/bin:/home/user/.pyenv/shims:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/var/lib/flatpak/exports/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin:/home/user/.local/share/JetBrains/Toolbox/scripts \
  external/rules_java++toolchains+remotejdk21_linux/bin/java '--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.resources=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED' '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED' '--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED' '--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED' '--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED' '--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED' '--add-opens=java.base/java.nio=ALL-UNNAMED' '--add-opens=java.base/java.lang=ALL-UNNAMED' '-Dsun.io.useCanonCaches=false' -XX:-CompactStrings -Xlog:disable '-Xlog:all=warning:stderr:uptime,level,tags' -jar external/rules_java++toolchains+remote_java_tools/java_tools/JavaBuilder_deploy.jar @bazel-out/k8-fastbuild/bin/src/test/java/com/google/j2cl/samples/java/libHelloWorldTest_generated_suite_lib.jar-0.params @bazel-out/k8-fastbuild/bin/src/test/java/com/google/j2cl/samples/java/libHelloWorldTest_generated_suite_lib.jar-1.params)
# Configuration: d4c5211d3491ee25bd7b54263a1e1a8b876173641d0da1bff9b2c3ffd34d12a4
# Execution platform: @@platforms//host:host
INFO: Elapsed time: 5.224s, Critical Path: 0.67s
INFO: 3 processes: 1139 action cache hit, 3 internal.
ERROR: Build did NOT complete successfully

Bazel version
8.3.1

Expected behavior
I would expect to be able to write unit tests for classes who's classpath contains a package named "java", e.g. com.acme.java.extensions.

Solution?
BUILD.bazel files can be placed anywhere relative to test source files without any expectation of folder structure (unlike other build systems such as Gradle that usually expect test sources to exist within a src/test/java directory relative to the build.gradle file).
I think the easiest solution might be to add an optional parameter to the j2cl_test rule to override the test sources root.
Alternatively, the test sources root could be derived from the test_class parameter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions