Maven 3 - How to add annotation processor dependency?

61,999

Solution 1

Add the dependency as an optional dependency (<optional>true</optional>). This will add the dependency under compilation, but will prevent it for being a transitive dependency:

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-jpamodelgen</artifactId>
  <version>${hibernate-jpamodelgen.version}</version>
  <optional>true</optional>
</dependency>

If you're creating an artifact in this module with all your dependencies in it (like a .war), you may use the <scope>provided</scope> instead. This both prevents the dependency to be transitive and to be included in the artifact the module produces.

Solution 2

The annotationProcessorPaths option can be used in recent versions of the Maven compiler plug-in:

<pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <annotationProcessorPaths>
                    <annotationProcessorPath>
                        <groupId>org.hibernate</groupId>
                        <artifactId>hibernate-jpamodelgen</artifactId>
                        <version>5.2.6.Final</version>
                    </annotationProcessorPath>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</pluginManagement>

That way the processor is separated from the actual project dependencies. This option is also picked up by the Eclipse M2E plug-in if annotation processing is enabled for the project.

Solution 3

For JDK 10 I really had to go a bit crazy to get it to work, Hoping someone finds this useful

<jaxb.version>2.3.0</jaxb.version>
<maven.hibernate.version>5.3.2.Final</maven.hibernate.version>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${maven.compiler.version}</version>
    <goals>
        <goal>compile</goal>
    </goals>
    <configuration>
        <outputDirectory>${project.build.directory}/generated-sources/annotations</outputDirectory>
        <annotationProcessorPaths>
            <annotationProcessorPath>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-jpamodelgen</artifactId>
                <version>${maven.hibernate.version}</version>
            </annotationProcessorPath>
            <annotationProcessorPath>
                <groupId>javax.xml.bind</groupId>
                <artifactId>jaxb-api</artifactId>
                <version>${jaxb.version}</version>
            </annotationProcessorPath>
        </annotationProcessorPaths>
        <annotationProcessors>
            <annotationProcessor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</annotationProcessor>
        </annotationProcessors>
        <compilerArgs>
            <arg>-AaddGeneratedAnnotation=false</arg>
        </compilerArgs>
        <compilerArguments>
            <AaddGeneratedAnnotation>false</AaddGeneratedAnnotation>
            <Adebug>true</Adebug>
        </compilerArguments>
        <failOnError>true</failOnError>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>${maven.hibernate.version}</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>${jaxb.version}</version>
            <type>jar</type>
        </dependency>
    </dependencies>
</plugin>

Solution 4

The problem is really in 3.* version of the maven-compiler-plugin. It acts a bit different from the 2.* version. In particular, it seems that maven-compiler-plugin3.* doesn't add its dependencies and build extensions to the classpath because it uses javax.tools instruments for running compile process. To get back the old behavior for maven-compiler-plugin you should use a new configuration property forceJavacCompilerUse:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
    <forceJavacCompilerUse>true</forceJavacCompilerUse>
</configuration>
....
</plugin>

Solution 5

Please take a look jpa-metamodels-with-maven

For further visitors, I found that there are some significant changes in maven-compiler-plugin 3.x series.

This is how I do this. (I'm the one who you linked)

The point is that my solution does not work with those 3.x series of maven-compiler-plugin.

<project ...>

  <build>

    <extensions>
      <extension>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-jpamodelgen</artifactId>
        <version>1.3.0.Final</version>
      </extension>
    </extensions>

    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.5.1</version> <!-- See this? -->
      </plugin>
    </plugins>

  </build>
</project>
Share:
61,999
bernie
Author by

bernie

Updated on June 05, 2021

Comments

  • bernie
    bernie almost 3 years

    I need to run an annotation processor on my project's sources. The annotation processor should not become a transitive dependency of the project since it's only needed for annotation processing and nothing else.

    Here is the complete (non-working) test pom I use for this:

    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>test</groupId>
      <artifactId>test</artifactId>
      <packaging>jar</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>Test annotations</name>
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <hibernate-jpamodelgen.version>1.2.0.Final</hibernate-jpamodelgen.version>
      </properties>
      <dependencies>
        <dependency>
          <groupId>javax</groupId>
          <artifactId>javaee-api</artifactId>
          <version>6.0</version>
          <scope>provided</scope>
        </dependency>
      </dependencies>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
              <annotationProcessors>
                <annotationProcessor>
                  org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</annotationProcessor>
              </annotationProcessors>
              <debug>true</debug>
              <optimize>true</optimize>
              <source>1.6</source>
              <target>1.6</target>
              <compilerArguments>
                <AaddGeneratedAnnotation>true</AaddGeneratedAnnotation>
                <Adebug>true</Adebug>
              </compilerArguments>
            </configuration>
            <dependencies>
              <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-jpamodelgen</artifactId>
                <version>${hibernate-jpamodelgen.version}</version>
              </dependency>
            </dependencies>
          </plugin>
        </plugins>
      </build>
    </project>
    

    I explicitly defined org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor as an annotation processor in the plugin configuration for tests and I know it shouldn't be required.

    The problem I'm encountering is that the hibernate-jpamodelgen dependency is not added to the compiler classpath so the annotation processor is not found and the build fails.

    As per this answer, I tried adding the dependency as a build extension (not sure I understand what those are supposed to be!) like so:

    <extensions>
      <extension>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-jpamodelgen</artifactId>
        <version>${hibernate-jpamodelgen.version}</version>
      </extension>
    </extensions>
    

    This also doesn't add hibernate-jpamodelgen to the compiler classpath.

    The only thing I found which works so far is adding the dependency to the project in the <dependencies> section. This has the unfortunate side-effect of adding hibernate-jpamodelgen as a transitive dependency afterwards which I want to avoid.

    My previous working setup uses the maven-processor-plugin plugin to achieve what I want. However, this plugin is not supported by eclipse m2e and the latest version of the maven-compiler-plugin now handles multiple compiler arguments properly so I'd rather use the latter.