bazel-contrib / bazel-contrib/rules_jvm
get_class_name incorrectly matches .net/.org/.io sub-packages inside com.* packages
- Dominant language
- Go
- Stars
- 54
- Forks
- 98
- Avg merge
- 6d 2h
- Merged PRs (30d)
- 7
Description
## Description
`get_class_name()` in `java/private/package.bzl` produces an incorrect `test_class` when a `com.*` Java package contains a sub-package named `net`, `org`, `io`, `ai`, `co`, `me`, or `dev`.
This is related to #104 but is a **different failure mode**: #104 is about uncommon TLDs not being recognized at all. This bug is about a known TLD prefix (`.net.`, `.org.`, etc.) being matched **inside** a `com.*` package name instead of at the top level.
## Example
Source path: `com/example/net/NetTest.java`
1. `get_class_name` converts it to `com.example.net.NetTest`
2. Scans `_PREFIXES = (".com.", ".org.", ".net.", ...)`
3. `.com.` is checked first via `name.find(".com.")` — but the string starts with `com.` (no leading dot), so it returns `-1`
4. `.net.` matches at position 12 inside `com.example.net.NetTest`
5. Returns `net.NetTest` instead of `com.example.net.NetTest`
Result: `Class not found: [net.NetTest]`
## Minimal reproduction
Unzip the attached `rules-jvm-bug-poc.zip` and run:
```bash
bazel test //src/test/java/...
```
**Expected:** Both tests pass.
**Actual:** `NetTest` fails with `Class not found: [net.NetTest]`, `UtilsTest` passes.
Reproduction project structure
```
├── .bazelrc # Java 17 toolchain
├── .bazelversion # 9.0.0
├── BUILD.bazel
├── MODULE.bazel # contrib_rules_jvm 0.32.0
└── src/test/java/
├── BUILD.bazel # java_test_suite with two tests
└── com/example/
├── net/NetTest.java # FAILS
└── utils/UtilsTest.java # PASSES
```
`src/test/java/BUILD.bazel`:
```python
load("@contrib_rules_jvm//java:defs.bzl", "java_test_suite")
java_test_suite(
name = "tests",
srcs = [
"com/example/net/NetTest.java",
"com/example/utils/UtilsTest.java",
],
deps = ["@maven//:junit_junit"],
)
```
## Root cause
In [`java/private/package.bzl`](https://github.com/bazel-contrib/rules_jvm/blob/main/java/private/package.bzl#L20-L31):
```python
_PREFIXES = (".com.", ".org.", ".net.", ".io.", ".ai.", ".co.", ".me.", ".dev.")
def get_class_name(package, src, prefixes=[]):
idx = src.rindex(".")
name = src[:idx].replace("/", ".")
# ...
for prefix in prefixes:
idx = name.find(prefix)
if idx != -1:
return name[idx + 1:]
```
`name.find(".com.")` fails when the string **starts** with `com.` because there's no dot at position -1. The scan then falls through to `.net.` which matches inside the string.
## Workaround
Pass `package_prefixes` to anchor the match:
```python
java_test_suite(
...
package_prefixes = [".com.example."],
)
```
## Affected packages
Any `com.*` (or `org.*`, etc.) package that has a sub-package matching one of the entries in `_PREFIXES`: `net`, `org`, `io`, `ai`, `co`, `me`, `dev`.
Contributor guide
Research direction
Start in java/private/package.bzl at get_class_name and review how package prefixes are matched. Unzip the reproduction project and run bazel test //src/test/java/... to confirm the NetTest failure. Done means both NetTest and UtilsTest pass without the incorrect net.NetTest class name.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100