javajarbazelbazel-rulesbazel-java

How to create Java library in Bazel from generated Java files


I have a custom Bazel rule which generates a bunch of Java files. The rule is something like this:

def _generator_java_impl(ctx):
   tree = ctx.actions.declare_directory(ctx.attr.name + "_srcs")

   # Actual generation of the Java files
   ctx.actions.run(
       ...
       outputs = [tree],
       ...
   )

   return [DefaultInfo(files = depset([tree]))]


generator_java = rule(
   implementation = _generator_java_impl,
   ...
)

In my BUILD file I am using that rule to generate the Java sources and to create a Java library from these sources:

generator_java(
   name = "generated_java",
   ...
)

java_library(
   name = "mylib",
   srcs = [":generated_java"]

It builds fine using bazel build //:mylib but my JAR file is empty (only MANIFEST is there and misses the Java classes)

I can test that bazel build //:generated_java really generates my Java files and the output folder is not empty.

Any ideas why my Java library is empty?


Solution

  • The Java rules do not support tree artifacts (what's returned from ctx.actions.declare_directory), and unfortunately, the rules fail on tree artifacts by silently doing nothing as you've discovered.

    The Java rules do support "source jars", though. A source jar is simply a ZIP archive with a .srcjar extension. The Java rules will compile the .java files within it. So, add a final step to your generator to zip up its outputs.