Depending on sources generated by Java annotation processors

1,134 views
Skip to first unread message

Erik Kuefler

unread,
Mar 30, 2015, 9:12:32 PM3/30/15
to bazel-...@googlegroups.com
Congratulations on the launch! As a former Blaze user I've been looking forward to this day for months and am hoping to convert all of my Gradle projects as soon as I can.

The first issue I've run into is how to depend on code generated by annotation processors. I have a processor that works similar to AutoValue, generating a builder class for an annotated value type which is then referenced by that type. I've exposed that in a java_library using exported_plugins and am depending on that library in a second library, but building that second library fails with "cannot find symbol" errors on all of my generated classes. I can see the generated .java files under mylib_sourcegenfiles in bazel-bin, so I know the processors were run successfully.

I think I probably need to include the generated sources in my library's srcs somehow, but I'm not sure how to do this. This seems tricky since the output sources aren't known until the processor has run, but assuming Google uses AutoValue or Dagger internally I suspect there's a way to do it that I'm not thinking of. Any pointers?

Ulf Adams

unread,
Mar 31, 2015, 6:44:52 AM3/31/15
to Erik Kuefler, bazel-...@googlegroups.com
This should work already - need more details. What symbol isn't found? A symbol in the runtime library? Is it defined in the java_library that exports the plugin?

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To post to this group, send email to bazel-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/e2163ff6-1447-4445-833a-c8ee68dceae5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Erik Kuefler

unread,
Mar 31, 2015, 12:33:29 PM3/31/15
to Ulf Adams, bazel-...@googlegroups.com
Sure. I've defined the following targets in an AnnotationProcessors package:
java_library(
name = "entityframework",
visibility = ["//visibility:public"],
plugins = [ # I think I don't actually need this one?
":EntityProcessor",
":EnumProcessor",
],
exported_plugins = [
":EntityProcessor",
":EnumProcessor",
]
)
java_plugin(
name = "EnumProcessor",
processor_class = "com.ekuefler.annotationprocessors.EnumProcessor",
srcs = SRCS,
deps = DEPS,
resources = RES,
)
java_plugin(
name = "EntityProcessor",
processor_class = "com.ekuefler.annotationprocessors.EntityProcessor",
srcs = SRCS,
deps = DEPS,
resources = RES,
)
I've defined the following target in a Model package:
java_library(
name = "Model",
srcs = glob(["**/src/main/java/**/*.java"]),
#plugins = [
# "//AnnotationProcessors:EntityProcessor",
# "//AnnotationProcessors:EnumProcessor",
#],
deps = [
"//AnnotationProcessors:entityframework",
"//external:guava",
],
)
Relying on the plugins directly (after making them public) instead of going through the library doesn't make a difference. Inside Model I have a class like this:
@Entity
public abstract class Group {
public static GroupBuilder newBuilder() {
return new GroupBuilder();
}

public abstract String getName();
}
GroupBuilder is generated by EntityProcessor, and I can see that it exists under the appropriate package at bazel-bin/Model/libModel_sourcegenfiles/. The error looks like this:

Model/src/main/java/com/ekuefler/model/Group.java:20: error: cannot find symbol
  public static GroupBuilder newBuilder() {
                ^
  symbol:   class GroupBuilder

  location: class Group


If this still isn't enough information I can try putting together a minimal repo on github.

Liam Miller-Cushon

unread,
Mar 31, 2015, 1:28:56 PM3/31/15
to Erik Kuefler, Ulf Adams, bazel-...@googlegroups.com
This should Just Work. I created a small demo with AutoValue: https://gist.github.com/cushon/0ffbe4f2a11141106695

In addition to the files under bazel-bin/.../libModel_sourcegenfiles/, you should see the generated sources in libModel-gensrc.jar and class files for the generated source in libModel.jar.

Have you tested these annotation processors with other build systems? Is there any chance they're generating sources during the final annotation processor round?

Erik Kuefler

unread,
Mar 31, 2015, 3:13:20 PM3/31/15
to Liam Miller-Cushon, Ulf Adams, bazel-...@googlegroups.com
Thanks for the demo, that helped narrow things down. Turned out that I was missing some files in my srcs, which was causing the processor to report some type errors. javac only shows a max of 100 errors, so it flooded with missing symbol errors before showing the actual root errors from the processor. Passing --javacopt="-Xmaxerrs 1000" lets me see the actual errors and adding the missing source files fixes things.

Menny Even Danan

unread,
May 4, 2016, 2:06:41 PM5/4/16
to bazel-discuss, cus...@google.com, ulf...@google.com, Alex Humesky, ca...@google.com
Liam,
Can you provide more details about annotation processors, specifically on Auto-Value and Dagger2.
We are using both libraries in our (very large) code-base. The annotated classes are part of the main app's code (it is not extracted into a standalone library).

Thanks

Liam Miller-Cushon

unread,
May 5, 2016, 1:23:50 AM5/5/16
to Menny Even Danan, bazel-discuss, Ulf Adams, Alex Humesky, Carmi Grushko
On Wed, May 4, 2016 at 11:06 AM, Menny Even Danan <men...@gmail.com> wrote:
Liam,
Can you provide more details about annotation processors, specifically on Auto-Value and Dagger2.
We are using both libraries in our (very large) code-base. The annotated classes are part of the main app's code (it is not extracted into a standalone library).

Hi, what details are you interested in? The autovalue example earlier in the thread still works (I updated it to use the current WORKSPACE syntax). Those build rules are roughly what we use internally: there's a public java_library that exports the declaration of the annotations and the java_plugin. Libraries only have to add a dependency on that target for the processor to be run when they're compiled.

Menny Even Danan

unread,
May 5, 2016, 8:58:55 AM5/5/16
to Liam Miller-Cushon, Alex Humesky, Carmi Grushko, Ulf Adams, bazel-discuss
I got my annotation processors to work, i'm just looking for details about _how_ it works.
For example, thr `bind` command, what is its purpose (I did not use it)? What are the `exports`? Etc.
One of thr things that i'm confused about is that we used Dagger 2.1, and that did not work with Bazel (worked with Gradle), but Dagger 2.2 worked with both.

Liam Miller-Cushon

unread,
May 5, 2016, 2:36:56 PM5/5/16
to Menny Even Danan, Alex Humesky, Carmi Grushko, Ulf Adams, bazel-discuss
On Thu, May 5, 2016 at 5:58 AM, Menny Even Danan <men...@gmail.com> wrote:
I got my annotation processors to work, i'm just looking for details about _how_ it works.
For example, thr `bind` command, what is its purpose (I did not use it)?

'bind' isn't needed anymore, the original example was out of date.
 
What are the `exports`? Etc.

 
One of thr things that i'm confused about is that we used Dagger 2.1, and that did not work with Bazel (worked with Gradle), but Dagger 2.2 worked with both.

Can you file a bug with repro instructions for the issue with 2.1?
Reply all
Reply to author
Forward
0 new messages