Using the AutoValue Code Generator in Eclipse

Home  >>  Common  >>  Using the AutoValue Code Generator in Eclipse

Using the AutoValue Code Generator in Eclipse

On March 4, 2014, Posted by , In Common,Eclipse, With 3 Comments

My colleague Moritz of EclipseSource recently came across Google Auto, a collection of Java code generators. AutoValue is one of them and generates Java code for immutable objects. It provides an annotation and an annotation processor to generate Java code for immutable value objects. The current version is labelled RC1 and a 1.0 release is soon to come.

The idea is to have an abstract class that defines the outside behavior and the annotation processor will do the rest. For each desired field, an abstract accessor method is defined. Finally a factory method is needed to create instances of the generated class.

@AutoValue
abstract class Person {
  static Person create( String name, int age ) {
    return new AutoValue_Person( name, age );
  }

  abstract String name();
  abstract int age();
}

After running the processor, you will also have an AutoValue_Person class that lives in the same package and implements the accessor methods to return the field values. It also implements equals, hashCode and toString. This is how the generated code looks like:

final class AutoValue_Person extends Person {
  private final String name;
  private final int age;

  AutoValue_Person(String name, int age) {
    if (name == null)
      throw new NullPointerException("Null name");
    this.name = name;
    this.age = age;
  }

  String name() {
    return name;
  }
  ...

  public String toString() {
    ...
  }

  public boolean equals(Object o) {
    ...
  }

  public int hashCode() {
    ...
  }
}

As you can see, there is no magic involved. The processor generates readable and debug-steppable code without any runtime-dependencies. Aspects like nullability, serialization, custom implementations of equals, hashCode and toString and more can be customized. Follow the link in the project’s readme for all the details.

I quite like to idea of a small tool that does one thing and does it good. A good share of writing EqualsTester was motivated through testing equals and hashCode for – you guess it – immutable value objects. If AutoValue would have been around then, it might have saved some effort. However, this tool would be of limited practical use if it didn’t integrate well into your IDE of choice.

Integrate AutoValue into Eclipse

When using AutoValue in an IDE you will likely want to have the code generated as soon as you save the source file. My IDE of choice is Eclipse and thus I took these steps to integrate the annotation processor in Eclipse.

Rules for annotation processing in Eclipse must be specified per project. Hence, the first thing is to enable annotation processing for the project that uses the processor (Project properties > Java Compiler > Annotation Processing). By default the generated code is written to a separate source folder (Generated source directory setting) so that it can be excluded from version control.

Next I told Eclipse where to find the annotation processor for @AutoValue annotations. The processor is packaged together with the annotation itself in the auto-value-1.0-rc1.jar. Starting with this jar and going along its dependency chain, I ended up with these libraries that are necessary to run the processor (all available from Maven Central):

  • auto-service-1.0-rc1.jar
  • guava-16.0.1.jar
  • jsr-305-2.0.3.jar
  • auto-value-1.0-rc1.jar


Well, everything comes at a price. However, adding these jars to the Factory Path is sufficient. The processor (re-)generates code for every @AutoValue annotated class within the project whenever I hit Ctrl+S – very sleek…

What is left, is to make the setup easily consumable for other team members. The problem here is to place the jars in a location that is portable across different developer computers. I didn’t find a solution other than checking the settings and the ~2MB of jars into the source code repository. While having binaries in a repository certainly isn’t desirable, having every team member pull the jars from some place is as bad. Please share your thoughts if you know a way out of this dilemma.

Rüdiger Herrmann

Rüdiger started writing software more than 20 years ago. From the very beginning he focused on a pragmatic approach to writing and delivering software.

His interests include promoting test driven development and agile methods to deliver clean code that works.

(EMail: rherrmann@codeaffine.com)

3 Comments so far:

  1. Laurent Asfaux says:

    I have no blog (yet) to share this comment in a more readable way, but I think you will find it useful anyway :-)

    Because those JARs are part of the build tools, you can share then as an OSGi plugin translated to a Maven dependency by Eclipse Tycho.
    This way you will be able to :
    - integrate Annotation processors JARs in a p2 update site in order to deploy and update them easily into Eclipse as Annotaion processors plugins (like the “org.eclipse.jst.ws.annotations.core” plug-in does for web service annotations)
    - use them in any Maven/Gradle (headless) build process as a Maven dependency

    > step 1: create a new project containing the AutoValue annotation processor JAR.
    > step 2: create a plugin.xml file to implement the following extensions points :
    - Annotation Category
    - Annotation Definition
    - Annotation Initializer
    - Annotation Processor
    http://help.eclipse.org/kepler/index.jsp?topic=%2Forg.eclipse.jst.ws.jaxws.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fjst%2Fws%2Fannotations%2Fcore%2FAnnotationDefinition.html

    Tycho provides several goals for the build/package/deploy tasks :

    > step 3. package-plugin : package a project into an OSGi plugin and publish it as a Maven artifact
    http://www.eclipse.org/tycho/sitedocs/tycho-packaging-plugin/package-plugin-mojo.html

    > step 4. feature and bundle publisher : provides a p2 repository ready to use to provision Eclipse with the plug-in build in the step 1
    https://docs.sonatype.org/display/TYCHO/Tycho-extras+-+FeaturesAndBundlesPublisher
    (the sample POM file of this link downloads an already existing plug-in, replace the download task by the packaging of you JAR to publish-and-deploy directly)
    - be careful to provide a category.xml file to put the published plug-in into a category of your repository, or you will never find this plug-in in the user interface of the Update Manager.

    To use your new AutoValue Annotation Processor OSGi plug-in in Eclipse :
    - in the Update Manager, browse to the URL or ZIP file containing the p2 repository
    - check the plug-in you want to install into Eclipse
    - any plug-in containing an annotation processor service implementation will appear in the “Factory path” configuration page

    At this point you will done 90% of the job : you will be able to share, deploy and update the AutoValue Annotaton Processor on your whole team thanks to the p2 “provisioning platform”.

    > step 5 : include the generated Maven artifact as an optional dependency and an AnnotationProcessor in your (headless) Maven/Gradle builds
    http://stackoverflow.com/questions/14322904/maven-3-how-to-add-annotation-processor-dependency

    • Rüdiger Herrmann says:

      Thanks so much Laurent for the exhaustive explanation. I definitely learned something new today: JST can also help with annotation processing. I am somewhat astonished that annotation processing tools are hosted there. I would have expected them to be part of JDT/APT.

  2. Éamonn McManus says:

    AutoValue is on Maven Central now, so if you are using Maven you should just be able to add a dependency on groupId com.google.auto.value and artifactId auto-value. If you also have the m2e-apt plugin, you shouldn’t need to configure the Factory Path manually; everything should Just Work.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>