bazel icon indicating copy to clipboard operation
bazel copied to clipboard

Source jar contents don't match the regular one's

Open tpasternak opened this issue 1 year ago • 1 comments

Description of the bug:

The directory structure of the java source jars do not reflect neither the java file's package statements, nor the bazel output jars

Which category does this issue belong to?

No response

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

  1. Create an empty bazel project and create a single file named pack/BUILD with contents as below:
genrule(
    name = "source",
    outs = ["foo/Lib.java"],
    cmd = """
    cat << EOF >> $@
package foo;
class Lib{}
""",
)

java_library(
    name = "lib",
    srcs = [":source"],
)
  1. Run this command bazelisk build //pack:liblib-src.jar //pack:liblib.jar

  2. Compare the contents. One file contains foo/Lib.class, while the other contains pack/foo/Lib.java

Which operating system are you running Bazel on?

Linux

What is the output of bazel info release?

7.1.1

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What's the output of git remote get-url origin; git rev-parse HEAD ?

No response

Is this a regression? If yes, please try to identify the Bazel commit where the bug was introduced.

No response

Have you found anything relevant by searching the web?

No response

Any other information, logs, or outputs that you want to share?

No response

tpasternak avatar May 06 '24 15:05 tpasternak

Thanks for the report. While I agree the inconsistency is not great, I think this is WAI.

  1. The class jar (liblib.jar in your example), is created from the contents of the output directory after running javac. So the directory structure is determined by the package directive in your class files. So what you probably want in your example is package pack.foo; and not package foo;
  2. The sources jar (liblib-src.jar), is created by packaging all source files. The files are not read (so the package declaration is unknown). However, some heuristic path rewriting is applied. As your example demonstrates, with arbitrary paths, this does not always do the right thing. However, things should be more well-behaved if your directory structure is under "well-known" roots, such as java or javatests (and also the maven-esque src/{main,test}). You can see the relevant heuristics currently in use here and here.

Hope this explanation helps. Happy to discuss further if there are any ideas for improving the situation.

hvadehra avatar May 08 '24 12:05 hvadehra

Ok, thanks for the explanation. I still think it would be better to apply data retrieved from package directive to both jars, but I agree it's a low priority one as long as it is possible to overcome it by sticking to the well-known roots

tpasternak avatar May 08 '24 16:05 tpasternak