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

Closed
gunnarmorling opened this issue Mar 14, 2019 · 15 comments · Fixed by #37044
Closed

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

gunnarmorling opened this issue Mar 14, 2019 · 15 comments · Fixed by #37044
Labels
area/devmode kind/enhancement New feature or request pinned Issue will never be marked as stale
Milestone

Comments

@gunnarmorling
Copy link
Contributor

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
Copy link
Member

dmlloyd commented Mar 14, 2019

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

@geoand
Copy link
Contributor

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
Copy link
Member

gsmet commented Mar 15, 2019

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

@geoand
Copy link
Contributor

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
Copy link

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
Copy link
Member

gsmet commented Mar 16, 2019 via email

@gunnarmorling
Copy link
Contributor Author

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
Copy link
Contributor

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) {

@famod
Copy link
Member

famod commented May 19, 2020

I just stumbled upon this. In my case it is hibernate-jpamodelgen.
Adding a provided dependency is less than ideal because we have many submodules (yes, we could define it to the root parent...) and hibernate-jpamodelgen has JaxB dependencies that I don't want to have on the compile or test (runtime) classpath.

PS: Noticed the problem because a message is printed on reload:

The following options were not recognized by any processor: '[fullyAnnotationConfigured]', line -1 in [unknown source]

cc @harthorst @tkalmar

@famod
Copy link
Member

famod commented Mar 11, 2021

I kind of lost track of what was changed for dev mode in the last months but I suppose this is still a problem? /cc @stuartwdouglas

In virtually all of the recent projects I'm seeing lately in my company we have the following annotation processors:

  • mapstruct
  • jpa-modelgen
  • immutables
  • and possibly lombok

Not having them (fully) supported in dev mode is a real issue because it is very likely you will touch something in dev mode that is subject to annotation processing.

Leaving that "class group" challenge aside for a moment, wouldn't it be a good first improvement to "just" read the processors from maven config and run them for every change?
Not sure I'm making sense at all, but I'd love to see some progress on this.

@famod
Copy link
Member

famod commented Mar 17, 2021

I almost submitted a "yay all is well" comment but I had second thoughts:

In a Quarkus 1.12.2 project we are setting up currently, all of the processors mentioned above do work, but only because Eclipse is triggering the processors!
This might also explain why we are seeing so many full reloads/restarts instead of smaller (agent based?) code swappings... (/cc @stuartwdouglas, does that make sense?)

Strangely, the provided dependency workaround doesn't work at all for us. 🤔 We might have a second look later.

@ghost
Copy link

ghost commented Apr 13, 2021

My setup/situation is similar to what @famod mentions above.

Annotation processors:

  • MapStruct
  • jpa-modelgen
  • Lombok

Instead of Eclipse I use IntelliJ IDEA. And in such a project with these annotation processors it seems to me that Quarkus has to do a full restart every time.

In another project, I use Kotlin without Lombok, MapStruct and jpa-modelgen. And there a lot of the changes can be applied with a hot replacement/code swapping (without full restart).

@FroMage
Copy link
Member

FroMage commented Sep 26, 2023

I have a fix for that pending in #36168 for Maven, if anybody wants to help with Gradle, help will be welcome ;)

@geoand
Copy link
Contributor

geoand commented Sep 26, 2023

@snazy would you be interested in ^?

@snazy
Copy link
Contributor

snazy commented Oct 2, 2023

Still have the plan to use Gradle's continuous build with Quarkus' dev-mode, but no so much progress yet (beside some very early experiments).

FroMage added a commit to FroMage/quarkus that referenced this issue Jan 12, 2024
FroMage added a commit to FroMage/quarkus that referenced this issue Jan 12, 2024
FroMage added a commit to FroMage/quarkus that referenced this issue Jan 12, 2024
FroMage added a commit to FroMage/quarkus that referenced this issue Jan 12, 2024
FroMage added a commit to FroMage/quarkus that referenced this issue Jan 15, 2024
@quarkus-bot quarkus-bot bot added this to the 3.7 - main milestone Jan 16, 2024
bpasson pushed a commit to bpasson/quarkus that referenced this issue Jan 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/devmode kind/enhancement New feature or request pinned Issue will never be marked as stale
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

8 participants