Skip to content
Cameron Beccario edited this page Jun 21, 2013 · 2 revisions

This page describes how to configure your Maven project to perform Grains generation. See here for a working sample.

Requirements

  • Java 7 or greater
  • Maven 2.2.1 or greater

Artifacts and Download

The Grains framework is published on Maven Central, and comprises several modules:

  • grains-core: functionality required for both code generation and runtime use of grains.
  • grains-generate: the code generator.
  • grains-plugin: a Maven plugin that invokes the generator.
  • grains-jackson: Jackson serialization support.
  • grains-msgpack: MessagePack serialization support.
  • grains-kryo: Kryo serialization support.

The modules are designed to introduce as few transitive dependencies as possible. For example, grains-core drags no dependencies into your project, and the (optional) serialization modules depend solely on the serialization libraries they are named after. The generator Maven plugin is of course used only at compile time.

How the Generator Works

When invoked, the generator scans the classpath for classes annotated with @GrainSchema. It then loads the classes and uses standard reflection to inspect their structure and generate .java files. These files are written to the canonical Maven location for generated sources: ${project.build.directory}/generated-sources/grains

For the generator to find the annotated classes, they must be compiled and be present on the classpath before the generator is invoked. There are two ways to accomplish this:

  1. PRE-COMPILE: Put the schemas in their own package and pre-compile that package during the generate-sources phase. This allows the schemas and the corresponding generated classes to co-exist in the same module.
  2. DEPENDENCY: Put the schemas in their own module and add as a dependency. This avoids the need for pre-compilation but means the schemas and corresponding generated classes are split between two modules (i.e., two .JARs).

The PRE-COMPILE approach is easiest configuration-wise, but care must be taken to ensure the pre-compiled code does not inadvertently use code that is meant to be compiled later during the normal compile phase. Otherwise weirdness ensues.

POM Configuration

The following steps assume your grain schemas are located in a package called com.acme.model.

First, add a runtime dependency on grains-core:

<dependency>
    <groupId>net.nullschool</groupId>
    <artifactId>grains-core</artifactId>
    <version>0.8.0</version>
</dependency>

The next steps depend on the generation approach you decide to take.

PRE-COMPILE Approach

Configure the compiler to compile the schema package during the generate-sources phase:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
        <source>1.7</source>
        <target>1.7</target>
    </configuration>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals><goal>compile</goal></goals>
            <configuration>
                <includes>
                    <include>com/acme/model/**</include>
                </includes>
            </configuration>
        </execution>
    </executions>
</plugin>

Next, configure the grains-plugin to run during the generate-sources phase:

<plugin>
    <groupId>net.nullschool</groupId>
    <artifactId>grains-plugin</artifactId>
    <version>0.8.0</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals><goal>generate</goal></goals>
        </execution>
    </executions>
</plugin>

The generator will search the com.acme.model package because that is the package configured for pre-compilation earlier in the POM. This behavior can be overridden by explicitly specifying the search packages with the plugin's <searchPackages> configuration tag.

DEPENDENCY Approach

Add a runtime dependency to the module containing the grain schemas.

Then, configure the grains-plugin to run during the generate-sources phase and include project dependencies in its search:

<plugin>
    <groupId>net.nullschool</groupId>
    <artifactId>grains-plugin</artifactId>
    <version>0.8.0</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals><goal>generate</goal></goals>
        </execution>
    </executions>
    <configuration>
        <searchPackages>
            <searchPackage>com.acme.model</searchPackage>
        </searchPackages>
        <searchProjectDependencies>true</searchProjectDependencies>
    </configuration>
</plugin>
Done!

Any interface in com.acme.model annotated with @GrainSchema will have a grain implementation generated when mvn compile is invoked.

Customizing Type Policies

As discussed in the Schema Writing Guide, the plugin can be configured to use a custom TypePolicy during code generation using the <typePolicy> configuration tag:

<configuration>
    <typePolicy>com.acme.model.MyTypePolicy.INSTANCE</typePolicy>
</configuration>

The tag value must be the fully qualified name of your custom TypePolicy class and the name of a static method or field that returns the type policy instance, separated by a dot.

This sample project demonstrates a working example.

Clone this wiki locally