Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotation processors are not re-run in dev mode #1502

Open
gunnarmorling opened this issue Mar 14, 2019 · 8 comments
Open

Annotation processors are not re-run in dev mode #1502

gunnarmorling opened this issue Mar 14, 2019 · 8 comments

Comments

@gunnarmorling
Copy link
Collaborator

@gunnarmorling gunnarmorling commented Mar 14, 2019

Testing Quarkus with an annotation processor that generates source code, the MapStruct team noticed that the AP isn't re-run after code changes in dev mode.

@dmlloyd

This comment has been minimized.

Copy link
Member

@dmlloyd dmlloyd commented Mar 14, 2019

I wonder if there is some way to just capture the arguments that were passed to javac originally.

@geoand

This comment has been minimized.

Copy link
Contributor

@geoand geoand commented Mar 15, 2019

Is there a way perhaps for Maven to write those arguments to a file from which we could read at recompile time?

@gsmet

This comment has been minimized.

Copy link
Member

@gsmet gsmet commented Mar 15, 2019

You don't have the capability to get the whole Maven configuration in a particular mojo?

@geoand

This comment has been minimized.

Copy link
Contributor

@geoand geoand commented Mar 15, 2019

I am not a Maven internals expert, but that does sounds like it could work.

But would looking at the configuration be enough to know figure out the compiler arguments?

@chris922

This comment has been minimized.

Copy link

@chris922 chris922 commented Mar 16, 2019

I got the dev-mode (partially) working with our MapStruct annotation processor (see mapstruct/mapstruct-examples#59 / mapstruct/mapstruct-examples@f05e97d):

Previously I defined the annotation processor using the maven-compile-plugin:

      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <annotationProcessorPaths>
            <path>
              <groupId>org.mapstruct</groupId>
              <artifactId>mapstruct-processor</artifactId>
              <version>${org.mapstruct.version}</version>
            </path>
          </annotationProcessorPaths>
        </configuration>
      </plugin>

This will not work together with the dev-mode. I assume the annotation processor path defined in the plugin will not be picked up automatically.

The solution was quite simple, just add our processor as a regular provided scoped dependency (thanks @filiphr for the idea). The processor itself contains a META-INF/services/javax.annotation.processing.Processor file so that the Java compiler will pick it up automatically.

    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-processor</artifactId>
      <version>${org.mapstruct.version}</version>
      <scope>provided</scope>
    </dependency>

One thing is still not working, and I guess it's quite hard to get this working:

The annotation processor will pick up files annotated with @Mapper, in case you make a change to this file everything is file. Nevertheless this class depends on other classes (in this example PersonDto and Person). When I make a change to one of these files the @Mapper annotated class will obviously not be regenerated and thus our annotation processor will not run.
Work-around: Make a temporary change to the @Mapper class so that it will be picked up again.

As already mentioned.. I think it will be quite hard to find a solution that will recompile the @Mapper file when a dependent class will be changed. Doing this in general could lead to recompiling a lot of files as soon as you changed a file.. maybe it's possible to just recompile the linked files that have an annotation processor!?

@gsmet

This comment has been minimized.

Copy link
Member

@gsmet gsmet commented Mar 16, 2019

@gunnarmorling

This comment has been minimized.

Copy link
Collaborator Author

@gunnarmorling gunnarmorling commented Mar 16, 2019

So I have no clear understanding of how the Quarkus' dev mode environment and the compiler interact, but it might be worth checking out what Gradle is doing in regards to "incremental annotation processing". In particular, they are using the originatingElement information passed to the Filer methods such as createSourceFile() to deduct which annotation processors need to be executed again after given classes have changed.

@geoand

This comment has been minimized.

Copy link
Contributor

@geoand geoand commented Mar 16, 2019

Very interesting @gunnarmorling, definitely something worth checking.

For the time being, the devmode / compiler interaction is quite simple, see:

public void compile(Set<File> filesToCompile, Context context) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.