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.
Describe the bug
The
j2cl_testrule 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(pathsrc/test/java/com/acme/java/extensions) will not compile becausej2cl_teststops too soon at the first "java" resulting in the generated files starting atsrc/test/java/com/acme/javainstead ofsrc/test/javalike I would expect.I can set
j2cl_test'stest_classparameter which fixes the class name used in the@J2clTestInputannotation (withouttest_classparameter:@J2clTestInput(.HelloWorldTest.class)), but then I run into the error shown in the output below.To Reproduce
examples/helloworldproject.helloworldlibtojava:samples/helloworld/src/test/java/com/google/j2cl/samples/helloworldlibto
samples/helloworld/src/test/java/com/google/j2cl/samples/javasamples/helloworld/src/test/java/com/google/j2cl/samples/java/BUILDto set thetest_classparameter manually:bazel build //src/test/java/com/google/j2cl/samples/java:HelloWorldTestBazel 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.bazelfiles 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 asrc/test/javadirectory relative to thebuild.gradlefile).I think the easiest solution might be to add an optional parameter to the
j2cl_testrule to override the test sources root.Alternatively, the test sources root could be derived from the
test_classparameter.