m2e-apt icon indicating copy to clipboard operation
m2e-apt copied to clipboard

Annotation processing not triggered

Open pyricau opened this issue 12 years ago • 19 comments

Hi there !

I'm the author of AndroidAnnotations, an APT library for Android projects.

We currently suggest our Maven / Eclipse users to use the maven-compiler-plugin to get the build to work with Maven, and then manually configure the Eclipse project by adding the processor JAR stored in M2_REPO (see here).

This clearly isn't ideal... @slandelle directed me to this plugin, which looks nice. I installed it, activated Automatically configure JDT APT, then Maven > Update Project Configuration, did a clean and... nothing happens.

One thing I noticed is that Java Compiler > Annotation Processing > Enable annotation processing is unchecked. If I check it, still nothing. If I run Maven > Update Project Configuration then... Java Compiler > Annotation Processing > Enable annotation processing becomes unchecked again ie (org.eclipse.jdt.apt.aptEnabled=false in .settings/org.eclipse.jdt.apt.core.prefs). Is that normal ?

We also tried using the maven-processor-plugin, and it lead to similar results.

I'm not certain the problem is on this plugin side though : we use the android-maven-plugin, in combination with the Android configurator for M2E and of course the official Eclipse Android plugin. This whole mix means things might not be done in a very maveny way... but if you have ideas on things I could try to solve this. I could try running the plugin in debug and look at what happens, if you have pointers on how to do that :) .

pyricau avatar Jun 14 '12 13:06 pyricau

I would need a test project to be able to reproduce the issue.

My gut feeling is the annotation processors are not detected by the configurator. The lookup is based on JDT APT behaviour, i.e. it's looking for jars containing service providers. If they're missing, then m2e-apt thinks there's nothing to configure.

Even if we changed the lookup mechanism in m2e-apt, there's a good chance the AP would be ignored by APT if the service providers are missing.

fbricon avatar Jun 14 '12 13:06 fbricon

I can provide a test project, but first... do you have the Android SDK installed ? The steps to get to a fully working maven+eclipse+android environment are... quite long, and I wouldn't you to spend too much time on this.

Meanwhile, here is the pom of my test project :

<?xml version="1.0" encoding="UTF-8"?>
<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>com.test.mavenandroid</groupId>
    <artifactId>mavenandroidtest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>apk</packaging>
    <name>mavenandroidtest</name>

    <properties>
        <platform.version>2.3.3</platform.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.google.android</groupId>
            <artifactId>android</artifactId>
            <version>${platform.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.googlecode.androidannotations</groupId>
            <artifactId>androidannotations</artifactId>
            <version>2.6-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.googlecode.androidannotations</groupId>
            <artifactId>androidannotations</artifactId>
            <classifier>api</classifier>
            <version>2.6-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>com.jayway.maven.plugins.android.generation2</groupId>
                <artifactId>android-maven-plugin</artifactId>
                <version>3.1.1</version>
                <configuration>
                    <androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile>
                    <assetsDirectory>${project.basedir}/assets</assetsDirectory>
                    <resourceDirectory>${project.basedir}/res</resourceDirectory>
                    <nativeLibrariesDirectory>${project.basedir}/src/main/native</nativeLibrariesDirectory>
                    <sdk>
                        <platform>10</platform>
                    </sdk>
                    <undeployBeforeDeploy>true</undeployBeforeDeploy>
                </configuration>
                <extensions>true</extensions>
            </plugin>

            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
<!--                    <annotationProcessors> -->
<!--                        <annotationProcessor>com.googlecode.androidannotations.AndroidAnnotationProcessor</annotationProcessor> -->
<!--                    </annotationProcessors> -->
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Notice that the <annotationProcessor> tag is commented. That's because AndroidAnnotations jar contains a service provider, so it's not needed. I just tried with and without it, just in case. mvn clean package from the command line works perfectly here, and the annotation processing runs.

The annotation processor is defined in the project dependency :

        <dependency>
            <groupId>com.googlecode.androidannotations</groupId>
            <artifactId>androidannotations</artifactId>
            <version>2.6-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>

The provided scope is there because otherwise the jar would be packaged by the android-maven-plugin in the resulting APK.

I noticed that you advise to define the dependency directly in the maven compiler plugin. I didn't try that yet, do you think it might have an impact ? I'll try this.

The dependency with <classifier>api</classifier> is just a dependency needed by the generated code. Since the artifact has the same name then the annotation processor, we use a classifier to distinguish it.

pyricau avatar Jun 14 '12 13:06 pyricau

Thx for the pom.

IM(F)O annotation processors are plugin dependencies, not project dependencies, hence my setup. But that would not change anything here.

I don't believe I need to setup a complete ADT environment to test what's going on, just need the jar containing the AP to check why it's not picked up.

Another explanation would have been java < 1.6 but that's not the case here.

I'll give a look at com.googlecode.androidannotations:androidannotations

fbricon avatar Jun 14 '12 13:06 fbricon

If the project is a regular java project (see below) , then annotation processing is properly configured.

<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>foo.bar</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
<dependencies>
    <dependency>
        <groupId>com.googlecode.androidannotations</groupId>
        <artifactId>androidannotations</artifactId>
        <version>2.5.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.googlecode.androidannotations</groupId>
        <artifactId>androidannotations</artifactId>
        <classifier>api</classifier>
        <version>2.5.1</version>
    </dependency>
</dependencies>
</project>

Another possible explanation is your eclipse project doesn't have the java nature installed. Before I set a complete ADT environment up to figure it out, can you add a link to your eclipse config files?

fbricon avatar Jun 14 '12 13:06 fbricon

I tried to move the dependency to the plugin. All of a sudden, APT wasn't triggered anymore in the command line (mvn clean package). I added back the <annotationProcessor /> block, and... got error: Annotation processor 'com.googlecode.androidannotations.AndroidAnnotationProcessor' not found.

<?xml version="1.0" encoding="UTF-8"?>
<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>com.test.mavenandroid</groupId>
    <artifactId>mavenandroidtest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>apk</packaging>
    <name>mavenandroidtest</name>

    <properties>
        <platform.version>2.3.3</platform.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.google.android</groupId>
            <artifactId>android</artifactId>
            <version>${platform.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.googlecode.androidannotations</groupId>
            <artifactId>androidannotations</artifactId>
            <classifier>api</classifier>
            <version>2.6-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>com.jayway.maven.plugins.android.generation2</groupId>
                <artifactId>android-maven-plugin</artifactId>
                <version>3.1.1</version>
                <configuration>
                    <androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile>
                    <assetsDirectory>${project.basedir}/assets</assetsDirectory>
                    <resourceDirectory>${project.basedir}/res</resourceDirectory>
                    <nativeLibrariesDirectory>${project.basedir}/src/main/native</nativeLibrariesDirectory>
                    <sdk>
                        <platform>10</platform>
                    </sdk>
                    <undeployBeforeDeploy>true</undeployBeforeDeploy>
                </configuration>
                <extensions>true</extensions>
            </plugin>

            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <annotationProcessors>
                        <annotationProcessor>com.googlecode.androidannotations.AndroidAnnotationProcessor</annotationProcessor>
                    </annotationProcessors>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>com.googlecode.androidannotations</groupId>
                        <artifactId>androidannotations</artifactId>
                        <version>2.6-SNAPSHOT</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

I'm still investigating (and waiting for @slandelle to help.. he's right next to me, finishing his Gatling release...)

Regarding my Eclipse config files, you mean .settings, .classpath, .project, right?

I was about to copy and paste that, but let's use GitHub instead https://github.com/pyricau/maven-aa-apt-eclipse :wink2:

pyricau avatar Jun 14 '12 14:06 pyricau

I just tried switching to maven-processor-plugin (@slandelle wanted that :)), defining the dependency directly in the plugin. It now works on both Maven and Eclipse... weird.

Changes : https://github.com/pyricau/maven-aa-apt-eclipse/compare/with_maven-processor-plugin

I'd still prefer to directly use the maven-compiler-plugin, but this will do if we can't find another way.

pyricau avatar Jun 14 '12 14:06 pyricau

Using m2e 1.1 (http://download.eclipse.org/technology/m2e/milestones/1.1/) on Juno (should work on Indigo too), the test project from master is configured with JDT APT.

I had to change the androidannotations dependencies to 2.5.1 though, since I don't know where to get the snapshots.

fbricon avatar Jun 14 '12 16:06 fbricon

Ok, I'll update m2e and see how it comes.

Sorry about the 2.6-SNAPSHOT :) Using 2.5.1 doesn't change a thing, you did the right thing. 2.6 has now been released anyway.

Thank you for your time!

pyricau avatar Jun 15 '12 07:06 pyricau

I'm having exactly the same issue with the querydsl apt processor (m2e 1.1 and Juno), the command line maven 3.0.4 works fine, just eclipse does not generate anything.

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                <generatedSourcesDirectory>${project.build.directory}/generated-sources/querydsl</generatedSourcesDirectory>

                <annotationProcessors>
                    <annotationProcessor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</annotationProcessor>
                </annotationProcessors>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>com.mysema.querydsl</groupId>
                    <artifactId>querydsl-apt</artifactId>
                    <version>2.6.0</version>
                </dependency>
                <dependency>
                    <groupId>org.apache.openejb</groupId>
                    <artifactId>javaee-api</artifactId>
                    <version>6.0-2</version>
                </dependency>
            </dependencies>
        </plugin>

mglauche avatar Jun 29 '12 12:06 mglauche

For the querydsl annotation processor, the problem comes from a limitation in Eclipse APT : as I explained in https://github.com/jbosstools/m2e-apt/issues/14#issuecomment-6327841 APs can only be detected if they're defined in META-INF/services/javax.annotation.processing.Processor and unfortunately querydsl-apt-XYZ..jar doesn't have these service providers.

I can think of 3 possible workarounds :

  • use the apt-one-jar classifier, which contains META-INF/services/javax.annotation.processing.Processor
   <dependency>
    <groupId>com.mysema.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
    <classifier>apt-one-jar</classifier>
    <version>${querydsl.version}</version>
   </dependency>
  • create and install a jar containing META-INF/services/javax.annotation.processing.Processor
  • use the maven-annotation-plugin

fbricon avatar Jun 29 '12 14:06 fbricon

and then, maybe, ask them to add such a file in their released jar :)

pyricau avatar Jun 29 '12 15:06 pyricau

They should actually split their querydsl-apt into 3 jars, one for each AP they provide. That way they could add one service provider per jar, without risking all APs to be invoked at once during a build.

fbricon avatar Jun 29 '12 15:06 fbricon

@fbricon The splitting has been done already https://github.com/mysema/querydsl/issues/180

It will be in the next release

timowest avatar Jun 30 '12 08:06 timowest

@fbricon: putting annotation processors as a dependency of the plugin rather than the project is appealing but unfortunately doesn't work in all setups; see square/dagger#194.

Actually, it seems like this only works as a side-effect of the maven-compiler-plugin using com.sun.tools.javac in-process (so the plugin dependencies are in the classpath):

  • As soon as you switch to maven-compile-plugin 3.0, which uses javax.tools.JavaCompiler by default, it no longer works (setting forceJavacCompilerUse to true gives you the old behavior, which processes annotations; see http://jira.codehaus.org/browse/MCOMPILER-202).
  • If you set fork to true (or -Dmaven.compiler.fork on the command-line), it doesn't work either, because the plugin dependencies aren't part of the classpath of the forked process.

The only way to reliably have annotations processed in Maven is to set the annotation processors as project dependencies with <scope>provided</scope> or <optional>true</optional>; or use the maven-processor-plugin which specifically includes plugin dependencies in the classpath: https://code.google.com/p/maven-annotation-plugin/issues/detail?id=46

tbroyer avatar Mar 27 '13 10:03 tbroyer

interesting. Thanks for the heads up

fbricon avatar Mar 27 '13 10:03 fbricon

I also experienced similar problems using this plugin. It finally turned out that if the jar containing annotation processors is a dependency that is open in the workspace as a project, then it won't be automatically added to the factory path. So if I develop an annotation processing jar, and I have another project in the workspace for the tests, importing the tests project won't add the dependency from the workspace to the factory path. If the APT project is closed or not added to the workspace, m2e-apt adds the dependency from the m2_repo correctly.

gabor-farkas avatar May 06 '14 08:05 gabor-farkas

Indeed Eclipse JDT APT does not support loading APs from open Eclipse projects, there's nothing I can do to change that. Your best bet is to open the project containing the AP in another workspace and do regular maven installs so they can be picked up in the first workspace (hopefully). And yes, it sucks big time.

fbricon avatar May 06 '14 09:05 fbricon

Well, now I configure the factory path manually, and when I change the AP source, I close the project referring the jar (otherwise eclipse seems to keep a lock on the file), do a maven install from the command line and then reopen the project using the AP.

gabor-farkas avatar May 06 '14 10:05 gabor-farkas

m2e-apt's code is now included in https://github.com/eclipse-m2e/m2e-core , please consider reporting issue to https://github.com/eclipse-m2e/m2e-core/issues if it's still relevant.

mickaelistria avatar Feb 17 '22 20:02 mickaelistria