quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.82k stars 2.69k forks source link

Quarkus Dev Mode and ErrorProne #26755

Open smil2k opened 2 years ago

smil2k commented 2 years ago

Discussed in https://github.com/quarkusio/quarkus/discussions/23142

Originally posted by **atamanroman** January 24, 2022 Has anyone a working Quarkus Dev Mode and [ErrorProne](http://errorprone.info) setup? Hot reload (triggered by an HTTP request) fails with: > Compilation Failed: > error: plug-in not found: ErrorProne My ErrorProne config: ``` maven-compiler-plugin ${compiler-plugin.version} UTF-8 true -parameters -XDcompilePolicy=simple -Xplugin:ErrorProne com.google.errorprone error_prone_core 2.10.0 ```

I got the exact same problem, I've tried to add errorprone to the dependencies of quarkus plugin without any luck.

<plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.platform.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>com.google.errorprone</groupId>
            <artifactId>error_prone_core</artifactId>
            <version>${error-prone.version}</version>
          </dependency>
        </dependencies>
      </plugin>

Quarkus version 2.10.2.Final Apache Maven 3.8.5 (3599d3414f046de2324203b78ddcf9b5e4388aa0) Maven home: /home/smil/.m2/wrapper/dists/apache-maven-3.8.5-bin/67203e94/apache-maven-3.8.5 Java version: 11.0.15, vendor: Private Build, runtime: /usr/lib/jvm/java-11-openjdk-amd64 Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "5.4.0-121-generic", arch: "amd64", family: "unix"

Steps to reproduce:

  1. Add errorprone to the compiler plugin.
  2. start dev mode (quarkus:dev) (Application compiles if necessary and starts)
  3. Make changes to the code, compilation will not work with the following output: Compilation Failed: error: plug-in not found: ErrorProne

Adding -X to the mvn options does not add any extra output. Rerunning quarkus:dev without recompile does everything correctly.

famod commented 2 years ago

This sounds like a known long standing issue, see #1502 and related issues.

Have you tried adding error_prone_core as a provided project dependency? See https://github.com/quarkusio/quarkus/issues/1502#issuecomment-473527113

andrebreves commented 1 year ago

I got Error Prone working in Quarkus Dev Mode by doing the following:

  1. Add error_prone_core as a provided dependency:
    <dependencies>
    .
    .
    .
    <dependency>
      <groupId>com.google.errorprone</groupId>
      <artifactId>error_prone_core</artifactId>
      <version>2.16</version>
      <scope>provided</scope>
    </dependency>
    .
    .
    .
    </dependencies>
  2. Add the following <jvmArgs> to the <configuration> section of the quarkus-maven-plugin (it is important to keep it as a one-liner, it won't work if there is a line break):
    <build>
    <plugins>
    .
    .
    .
      <plugin>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.platform.version}</version>
        <extensions>true</extensions>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
              <goal>generate-code</goal>
              <goal>generate-code-tests</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
            <jvmArgs>--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED  --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</jvmArgs>
        </configuration>
      </plugin>
    .
    .
    .
    </plugins>
    </build>
  3. Add -XDcompilePolicy=simple and -Xplugin:ErrorProne to the <compilerArgs> section of the maven-compiler-plugin:
    <build>
    <plugins>
    .
    .
    .
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
        <configuration>
          <compilerArgs>
            <arg>-parameters</arg>
            <arg>-XDcompilePolicy=simple</arg>
            <arg>-Xplugin:ErrorProne</arg>
          </compilerArgs>
        </configuration>
      </plugin>
    .
    .
    .
    </plugins>
    </build>
  4. Create the .mvn/jvm.config file as explained in the Maven section of the Error Prone installation guide.
andrebreves commented 1 year ago

Now I'm struggling to get NullAway (a Error Prone plugin) working inside dev mode.

I tried declaring NullAway also as a provided dependency:

  <dependencies>
.
.
.
    <dependency>
      <groupId>com.google.errorprone</groupId>
      <artifactId>error_prone_core</artifactId>
      <version>2.16</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.uber.nullaway</groupId>
      <artifactId>nullaway</artifactId>
      <version>0.10.5</version>
      <scope>provided</scope>
    </dependency>
.
.
.
  </dependencies>
  <build>
    <plugins>
.
.
.
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
        <configuration>
          <compilerArgs>
            <arg>-parameters</arg>
            <arg>-XDcompilePolicy=simple</arg>
            <arg>-Xplugin:ErrorProne -Xep:NullAway:WARN -XepOpt:NullAway:AnnotatedPackages=com.foo</arg>
          </compilerArgs>
          <showWarnings>true</showWarnings>
        </configuration>
      </plugin>
.
.
.
    </plugins>
 </build>

But when I enter dev mode it fails as if Error Prone doesn't know about NullAway:

Fatal error compiling: NullAway is not a valid checker name -> [Help 1]

I was able to make it work for the first compilation when I enter dev mode by also informing <annotationProcessorPaths>:

  <build>
    <plugins>
.
.
.
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
        <configuration>
          <compilerArgs>
            <arg>-parameters</arg>
            <arg>-XDcompilePolicy=simple</arg>
            <arg>-Xplugin:ErrorProne -Xep:NullAway:ERROR -XepOpt:NullAway:AnnotatedPackages=com.foo</arg>
          </compilerArgs>
          <annotationProcessorPaths>
            <path>
              <groupId>com.google.errorprone</groupId>
              <artifactId>error_prone_core</artifactId>
              <version>2.16</version>
            </path>
            <path>
               <groupId>com.uber.nullaway</groupId>
               <artifactId>nullaway</artifactId>
               <version>0.10.5</version>
            </path>
          </annotationProcessorPaths>
          <showWarnings>true</showWarnings>
        </configuration>
.
.
.
    </plugins>
 </build>

But any subsequent recompilation inside dev mode fails with the same message:

NullAway is not a valid checker name

I wonder if it would be feasible for quarkus-maven-plugin to support the <annotationProcessorPaths> parameter and implement it inside dev mode.

wjglerum commented 1 year ago

I just ran in the same problem @smil2k! Managed to get Error Prone itself running again in dev mode with the steps @andrebreves suggested above, but I'm now running into the same problem as you with NullAway. Did you manage to find another workaround? For now I'll just disable NullAway again.

gaetanBloch commented 1 year ago

I just tried today with the following configuration for ErrorProne and NullAway and so far I got no issue.

       <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${maven-compiler-plugin.version}</version>
          <configuration>
            <compilerArgs>
              <arg>-parameters</arg>
              <arg>-XDcompilePolicy=simple</arg>
              <arg>-Xplugin:ErrorProne -Xep:NullAway:ERROR -XepOpt:NullAway:AnnotatedPackages=foor.bar</arg>
            </compilerArgs>
            <annotationProcessorPaths>
              <path>
                <groupId>com.google.errorprone</groupId>
                <artifactId>error_prone_core</artifactId>
                <version>${error_prone_core.version}</version>
              </path>
              <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
              </path>
              <path>
                <groupId>com.uber.nullaway</groupId>
                <artifactId>nullaway</artifactId>
                <version>${nullaway.version}</version>
              </path>
            </annotationProcessorPaths>
          </configuration>
        </plugin>

Please note that I am using Quarkus 3.0.1.Final

wjglerum commented 1 year ago

~Also gave it a try, but seems to fail with the following exception when I some code, using Java 17 here~

Never mind that was another error related to an invalid/empty compiler arg passed to the plugin.

java.lang.IllegalArgumentException: error: invalid flag: 
    at jdk.compiler/com.sun.tools.javac.main.Arguments.reportDiag(Arguments.java:889)
    at jdk.compiler/com.sun.tools.javac.main.Arguments.doProcessArgs(Arguments.java:366)
    at jdk.compiler/com.sun.tools.javac.main.Arguments.processArgs(Arguments.java:347)
    at jdk.compiler/com.sun.tools.javac.main.Arguments.init(Arguments.java:246)
    at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:191)
    at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:119)
    at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:68)
    at io.quarkus.deployment.dev.JavaCompilationProvider.compile(JavaCompilationProvider.java:97)
    at io.quarkus.deployment.dev.QuarkusCompiler.compile(QuarkusCompiler.java:226)
    at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.checkForChangedClasses(RuntimeUpdatesProcessor.java:727)
    at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.doScan(RuntimeUpdatesProcessor.java:461)
    at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.doScan(RuntimeUpdatesProcessor.java:441)
    at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$4.handle(VertxHttpHotReplacementSetup.java:152)
    at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$4.handle(VertxHttpHotReplacementSetup.java:139)
    at io.vertx.core.impl.ContextBase.lambda$null$0(ContextBase.java:137)
    at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:264)
    at io.vertx.core.impl.ContextBase.lambda$executeBlocking$1(ContextBase.java:135)
    at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
    at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
    at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:833)
wjglerum commented 1 year ago

I just tried today with the following configuration for ErrorProne and NullAway and so far I got no issue.

       <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${maven-compiler-plugin.version}</version>
          <configuration>
            <compilerArgs>
              <arg>-parameters</arg>
              <arg>-XDcompilePolicy=simple</arg>
              <arg>-Xplugin:ErrorProne -Xep:NullAway:ERROR -XepOpt:NullAway:AnnotatedPackages=foor.bar</arg>
            </compilerArgs>
            <annotationProcessorPaths>
              <path>
                <groupId>com.google.errorprone</groupId>
                <artifactId>error_prone_core</artifactId>
                <version>${error_prone_core.version}</version>
              </path>
              <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
              </path>
              <path>
                <groupId>com.uber.nullaway</groupId>
                <artifactId>nullaway</artifactId>
                <version>${nullaway.version}</version>
              </path>
            </annotationProcessorPaths>
          </configuration>
        </plugin>

Please note that I am using Quarkus 3.0.1.Final

This indeed works for me on the initial request in dev mode, does it also still work for you when you make a change in the code and make another request? Cause for me it still gives my the following error:

com.google.errorprone.InvalidCommandLineOptionException: NullAway is not a valid checker name
    at com.google.errorprone.scanner.ScannerSupplier.lambda$applyOverrides$10(ScannerSupplier.java:194)
    at com.google.common.collect.SingletonImmutableBiMap.forEach(SingletonImmutableBiMap.java:68)
    at com.google.errorprone.scanner.ScannerSupplier.applyOverrides(ScannerSupplier.java:188)
    at com.google.errorprone.ErrorProneAnalyzer.lambda$scansPlugins$0(ErrorProneAnalyzer.java:79)
    at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers.java:183)
    at com.google.errorprone.ErrorProneAnalyzer.finished(ErrorProneAnalyzer.java:156)
    at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:132)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1394)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1341)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:933)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
    at io.quarkus.deployment.dev.JavaCompilationProvider.compile(JavaCompilationProvider.java:100)
    at io.quarkus.deployment.dev.QuarkusCompiler.compile(QuarkusCompiler.java:226)
    at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.checkForChangedClasses(RuntimeUpdatesProcessor.java:727)
    at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.doScan(RuntimeUpdatesProcessor.java:461)
    at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.doScan(RuntimeUpdatesProcessor.java:441)
    at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$4.handle(VertxHttpHotReplacementSetup.java:152)
    at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$4.handle(VertxHttpHotReplacementSetup.java:139)
    at io.vertx.core.impl.ContextBase.lambda$null$0(ContextBase.java:137)
    at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:264)
    at io.vertx.core.impl.ContextBase.lambda$executeBlocking$1(ContextBase.java:135)
    at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
    at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
    at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:833)
gaetanBloch commented 1 year ago

I have no problem with Either Erroprone or Nullaway whether it's the first request or the following ones.

Though, I have one issue regarding excluding field annotations which is very useful for injected fields with Dagger or Guice and in my case, Mocks.

-XepOpt:NullAway:ExcludeFieldAnnotations=io.quarkus.test.junit.mockito.InjectMock

This doesn't work and Nullaway is popping me an Error as the field is Injected with a Mock for testing purpose.

@InjectMock
FooService service

I had to switch to WARN so that my tests can pass.

wjglerum commented 1 year ago

I have no problem with Either Erroprone or Nullaway whether it's the first request or the following ones.

Though, I have one issue regarding excluding field annotations which is very useful for injected fields with Dagger or Guice and in my case, Mocks.

-XepOpt:NullAway:ExcludeFieldAnnotations=io.quarkus.test.junit.mockito.InjectMock

This doesn't work and Nullaway is popping me an Error as the field is Injected with a Mock for testing purpose.

@InjectMock
FooService service

I had to switch to WARN so that my tests can pass.

Which Java version are you using @gaetanBloch ? And can you maybe share the full pom?

gaetanBloch commented 1 year ago

I am using Java 17

❯ java -version
openjdk version "17.0.7" 2023-04-18
OpenJDK Runtime Environment Temurin-17.0.7+7 (build 17.0.7+7)
OpenJDK 64-Bit Server VM Temurin-17.0.7+7 (build 17.0.7+7, mixed mode)

I can only partially share the POM Parent as I'm working on a governement project :

<?xml version="1.0" ?>
<project
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://maven.apache.org/POM/4.0.0"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
  <modelVersion>4.0.0</modelVersion>

  <groupId>foo.bar</groupId>
  <artifactId>parent</artifactId>
  <version>${revision}</version>
  <packaging>pom</packaging>

  <properties>
    <!-- Actual project version -->
    <revision>1.0.0-SNAPSHOT</revision>

    <!-- Java version -->
    <java.version>17</java.version>

    <!-- Encoding -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <!-- Maven versions and plugins -->
    <maven.version>3.9.1</maven.version>
    <maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <maven.compiler.target>${java.version}</maven.compiler.target>
    <maven.compiler.release>${java.version}</maven.compiler.release>
    <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
    <maven-wrapper-plugin.version>3.2.0</maven-wrapper-plugin.version>
    <maven-enforcer-plugin.version>3.3.0</maven-enforcer-plugin.version>
    <maven-surefire-plugin.version>3.0.0</maven-surefire-plugin.version>
    <maven-versions-plugin.version>2.7</maven-versions-plugin.version>
    <maven-javadoc-plugin.version>3.5.0</maven-javadoc-plugin.version>
    <git-commit-id-plugin.version>5.0.0</git-commit-id-plugin.version>
    <spotbugs-maven-plugin.version>4.7.3.4</spotbugs-maven-plugin.version>
    <maven-pmd-plugin.version>3.20.0</maven-pmd-plugin.version>
    <maven-checkstyle-plugin.version>3.2.2</maven-checkstyle-plugin.version>
    <properties-maven-plugin.version>1.1.0</properties-maven-plugin.version>
    <checkstyle.version>10.10.0</checkstyle.version>
    <owasp-dependency-check-plugin.version>8.2.1</owasp-dependency-check-plugin.version>

    <skipTests>false</skipTests>
    <skipITs>true</skipITs>

    <!-- Quarkus -->
    <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
    <quarkus.platform.version>3.0.1.Final</quarkus.platform.version>

    <!-- Misc -->
    <lombok.version>1.18.26</lombok.version>
    <error_prone_core.version>2.18.0</error_prone_core.version>
    <nullaway.version>0.10.10</nullaway.version>

    <!-- Tests -->
    <assertj-core.version>3.24.2</assertj-core.version>
    <awaitility.version>4.2.0</awaitility.version>
    <jacoco.version>0.8.9</jacoco.version>

    <!-- Sonar -->
    <sonar-maven-plugin.version>3.9.1.2184</sonar-maven-plugin.version>
    <sonar.coverage.jacoco.xmlReportPaths>
      ${project.basedir}/target/jacoco-report/jacoco.xml
    </sonar.coverage.jacoco.xmlReportPaths>
    <sonar.qualitygate.wait>true</sonar.qualitygate.wait>
  </properties>

  <modules>
    <module>build-tools</module>
    <module>utils</module>
    <module>common-application</module>
    <module>common-domain</module>
    <module>common-infrastructure</module>
    <module>common-presentation</module>
    <module>common-core</module>
    <module>services</module>
  </modules>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>${quarkus.platform.artifact-id}</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

      <!-- Misc -->
      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
        <scope>provided</scope>
      </dependency>
      <dependency>
        <groupId>com.github.spotbugs</groupId>
        <artifactId>spotbugs</artifactId>
        <version>${spotbugs.version}</version>
      </dependency>

      <!-- Tests -->
      <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>${assertj-core.version}</version>
        <scope>test</scope>
      </dependency>
      <dependency>
        <groupId>org.awaitility</groupId>
        <artifactId>awaitility</artifactId>
        <version>${awaitility.version}</version>
        <scope>test</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <!-- Error prone -->
    <dependency>
      <groupId>com.google.errorprone</groupId>
      <artifactId>error_prone_core</artifactId>
      <version>${error_prone_core.version}</version>
      <scope>provided</scope>
    </dependency>
    <!-- NullAway -->
    <dependency>
      <groupId>com.uber.nullaway</groupId>
      <artifactId>nullaway</artifactId>
      <version>${nullaway.version}</version>
      <scope>provided</scope>
    </dependency>
    <!-- Jacoco -->
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jacoco</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <!-- Maven Build Cache -->
    <extensions>
      <extension>
        <groupId>org.apache.maven.extensions</groupId>
        <artifactId>maven-build-cache-extension</artifactId>
        <version>1.0.0</version>
      </extension>
    </extensions>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>io.github.git-commit-id</groupId>
        <artifactId>git-commit-id-maven-plugin</artifactId>
      </plugin>

      <!-- https://maven.apache.org/plugins/maven-pmd-plugin/ -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-pmd-plugin</artifactId>
        <version>${maven-pmd-plugin.version}</version>
        <configuration>
          <rulesets>
            <ruleset>whizbang/pmd-ruleset.xml</ruleset>
          </rulesets>
          <printFailingErrors>true</printFailingErrors>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>check</goal>
            </goals>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>com.example.whizbang</groupId>
            <artifactId>build-tools</artifactId>
            <version>1.0</version>
          </dependency>
        </dependencies>
      </plugin>
      <!-- https://maven.apache.org/plugins/maven-checkstyle-plugin/ -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
        <version>${maven-checkstyle-plugin.version}</version>
        <configuration>
          <suppressionsLocation>whizbang/checkstyle-suppressions.xml</suppressionsLocation>
          <configLocation>whizbang/checkstyle.xml</configLocation>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>check</goal>
            </goals>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>com.example.whizbang</groupId>
            <artifactId>build-tools</artifactId>
            <version>1.0</version>
          </dependency>
          <dependency>
            <groupId>com.puppycrawl.tools</groupId>
            <artifactId>checkstyle</artifactId>
            <version>${checkstyle.version}</version>
          </dependency>
        </dependencies>
      </plugin>
      <!-- Jacoco -->
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>${jacoco.version}</version>
        <executions>
          <execution>
            <id>default-prepare-agent</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
            <phase>validate</phase>
            <configuration>
              <exclClassLoaders>*QuarkusClassLoader</exclClassLoaders>
              <destFile>${project.build.directory}/jacoco-quarkus.exec</destFile>
              <append>true</append>
            </configuration>
          </execution>
          <execution>
            <id>default-prepare-agent-integration</id>
            <goals>
              <goal>prepare-agent-integration</goal>
            </goals>
            <configuration>
              <destFile>${project.build.directory}/jacoco-quarkus.exec</destFile>
              <append>true</append>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>

    <pluginManagement>
      <plugins>
        <!-- https://maven.apache.org/plugins/maven-wrapper-plugin/ -->
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-wrapper-plugin</artifactId>
          <version>${maven-wrapper-plugin.version}</version>
        </plugin>
        <!-- https://maven.apache.org/enforcer/maven-enforcer-plugin/ -->
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-enforcer-plugin</artifactId>
          <version>${maven-enforcer-plugin.version}</version>
          <executions>
            <execution>
              <id>enforce-versions</id>
              <goals>
                <goal>enforce</goal>
              </goals>
            </execution>
            <execution>
              <id>enforce-dependencyConvergence</id>
              <configuration>
                <rules>
                  <DependencyConvergence />
                </rules>
                <fail>true</fail>
              </configuration>
              <goals>
                <goal>enforce</goal>
              </goals>
            </execution>
          </executions>
          <configuration>
            <rules>
              <requireMavenVersion>
                <message>
                  You are running an older version of Maven. The project requires at least Maven
                  ${maven.version}
                </message>
                <version>[${maven.version},)</version>
              </requireMavenVersion>
              <requireJavaVersion>
                <message>
                  You are running an incompatible version of Java. The project supports only JDK 17 to 20.
                </message>
                <version>[17,21)</version>
              </requireJavaVersion>
            </rules>
          </configuration>
        </plugin>
        <!-- https://maven.apache.org/plugins/maven-compiler-plugin/ -->
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${maven-compiler-plugin.version}</version>
          <configuration>
            <compilerArgs>
              <arg>-parameters</arg>
              <arg>-XDcompilePolicy=simple</arg>
              <arg>
                -Xplugin:ErrorProne -Xep:NullAway:WARN
              </arg>
               <arg>
                 -XepOpt:NullAway:AnnotatedPackages=foo.bar
              </arg>
               <arg>
                -XepOpt:NullAway:ExcludeFieldAnnotations=io.quarkus.test.junit.mockito.InjectMock
              </arg>
            </compilerArgs>
            <annotationProcessorPaths>
              <path>
                <groupId>com.google.errorprone</groupId>
                <artifactId>error_prone_core</artifactId>
                <version>${error_prone_core.version}</version>
              </path>
              <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
              </path>
              <path>
                <groupId>com.uber.nullaway</groupId>
                <artifactId>nullaway</artifactId>
                <version>${nullaway.version}</version>
              </path>
            </annotationProcessorPaths>
            <encoding>${project.build.sourceEncoding}</encoding>
            <source>${maven.compiler.source}</source>
            <target>${maven.compiler.target}</target>
            <release>${maven.compiler.release}</release>
          </configuration>
        </plugin>
        <!-- https://maven.apache.org/plugins/maven-versions-plugin/ -->
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>versions-maven-plugin</artifactId>
          <version>${maven-versions-plugin.version}</version>
        </plugin>
        <!-- https://maven.apache.org/plugins/maven-surefire-plugin/ -->
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>${maven-surefire-plugin.version}</version>
          <configuration>
            <systemPropertyVariables>
              <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
              <maven.home>${maven.home}</maven.home>
            </systemPropertyVariables>
          </configuration>
        </plugin>
        <!-- https://maven.apache.org/plugins/maven-failsafe-plugin/ -->
        <plugin>
          <artifactId>maven-failsafe-plugin</artifactId>
          <version>${maven-surefire-plugin.version}</version>
          <executions>
            <execution>
              <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
              </goals>
              <configuration>
                <systemPropertyVariables>
                  <java.util.logging.manager>
                    org.jboss.logmanager.LogManager
                  </java.util.logging.manager>
                  <maven.home>${maven.home}</maven.home>
                  <quarkus.test.arg-line>${argLine}</quarkus.test.arg-line>
                  <quarkus.test.profile>integration</quarkus.test.profile>
                </systemPropertyVariables>
              </configuration>
            </execution>
          </executions>
        </plugin>
        <!-- https://maven.apache.org/plugins/maven-javadoc-plugin/ -->
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-javadoc-plugin</artifactId>
          <version>${maven-javadoc-plugin.version}</version>
          <configuration>
            <source>${maven.compiler.source}</source>
          </configuration>
        </plugin>
        <!-- https://maven.apache.org/plugins/git-commit-id/ -->
        <plugin>
          <groupId>io.github.git-commit-id</groupId>
          <artifactId>git-commit-id-maven-plugin</artifactId>
          <version>${git-commit-id-plugin.version}</version>
          <executions>
            <execution>
              <id>get-the-git-infos</id>
              <goals>
                <goal>revision</goal>
              </goals>
              <phase>validate</phase>
            </execution>
          </executions>
          <configuration>
            <failOnNoGitDirectory>true</failOnNoGitDirectory>
            <failOnUnableToExtractRepoInfo>true</failOnUnableToExtractRepoInfo>
            <generateGitPropertiesFile>true</generateGitPropertiesFile>
            <skipPoms>false</skipPoms>
            <format>json</format>
            <includeOnlyProperties>
              <includeOnlyProperty>^git.branch$</includeOnlyProperty>
              <includeOnlyProperty>^git.build.time$</includeOnlyProperty>
              <includeOnlyProperty>^git.build.user.name$</includeOnlyProperty>
              <includeOnlyProperty>^git.build.user.email$</includeOnlyProperty>
              <includeOnlyProperty>^git.build.version$</includeOnlyProperty>
              <includeOnlyProperty>^git.commit.author.time$</includeOnlyProperty>
              <includeOnlyProperty>^git.commit.id.abbrev$</includeOnlyProperty>
              <includeOnlyProperty>^git.commit.id.describe$</includeOnlyProperty>
              <includeOnlyProperty>^git.commit.id.full$</includeOnlyProperty>
              <includeOnlyProperty>^git.commit.message.full$</includeOnlyProperty>
              <includeOnlyProperty>^git.commit.message.short$</includeOnlyProperty>
              <includeOnlyProperty>^git.commit.time$</includeOnlyProperty>
              <includeOnlyProperty>^git.commit.user.name$</includeOnlyProperty>
              <includeOnlyProperty>^git.commit.user.email$</includeOnlyProperty>
              <includeOnlyProperty>^git.dirty$</includeOnlyProperty>
              <includeOnlyProperty>^git.remote.origin.url$</includeOnlyProperty>
              <includeOnlyProperty>^git.tags$</includeOnlyProperty>
              <includeOnlyProperty>^git.total.commit.count$</includeOnlyProperty>
            </includeOnlyProperties>
            <verbose>false</verbose>
            <commitIdGenerationMode>full</commitIdGenerationMode>
            <generateGitPropertiesFilename>
              ${project.build.outputDirectory}/git.properties.json
            </generateGitPropertiesFilename>
          </configuration>
        </plugin>
        <!-- https://spotbugs.github.io/spotbugs-maven-plugin/ -->
        <plugin>
          <groupId>com.github.spotbugs</groupId>
          <artifactId>spotbugs-maven-plugin</artifactId>
          <version>${spotbugs-maven-plugin.version}</version>
          <configuration>
            <includeFilterFile>spotbugs-security-include.xml</includeFilterFile>
            <excludeFilterFile>spotbugs-security-exclude.xml</excludeFilterFile>
            <plugins>
              <plugin>
                <groupId>com.h3xstream.findsecbugs</groupId>
                <artifactId>findsecbugs-plugin</artifactId>
                <version>1.12.0</version>
              </plugin>
            </plugins>
            <execution>
              <id>spotbugs-check</id>
              <goals>
                <goal>check</goal>
              </goals>
              <phase>verify</phase>
            </execution>
          </configuration>
        </plugin>
        <!-- https://maven.apache.org/plugins/quarkus-maven-plugin/ -->
        <plugin>
          <groupId>${quarkus.platform.group-id}</groupId>
          <artifactId>quarkus-maven-plugin</artifactId>
          <version>${quarkus.platform.version}</version>
          <extensions>true</extensions>
          <executions>
            <execution>
              <goals>
                <goal>build</goal>
                <goal>generate-code</goal>
                <goal>generate-code-tests</goal>
              </goals>
            </execution>
          </executions>
          <configuration>
            <jvmArgs>
              --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
              --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
              --add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
              --add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
              --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
              --add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
              --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
              --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
              --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
              --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
            </jvmArgs>
          </configuration>
        </plugin>
        <!-- OWASP -->
        <plugin>
          <groupId>org.owasp</groupId>
          <artifactId>dependency-check-maven</artifactId>
          <version>${owasp-dependency-check-plugin.version}</version>
          <configuration>
            <!-- Fail only when detecting High Vulnerability issues -->
            <failBuildOnCVSS>7</failBuildOnCVSS>
            <suppressionFiles>
              <suppressionFile>whizbang/dependency-cpe-suppression.xml</suppressionFile>
            </suppressionFiles>
          </configuration>
          <executions>
            <execution>
              <goals>
                <goal>check</goal>
              </goals>
              <phase>verify</phase>
            </execution>
          </executions>
          <dependencies>
            <dependency>
              <groupId>com.example.whizbang</groupId>
              <artifactId>build-tools</artifactId>
              <version>1.0</version>
            </dependency>
          </dependencies>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

  <reporting>
    <plugins>
      <!-- https://spotbugs.github.io/spotbugs-maven-plugin/ -->
      <plugin>
        <groupId>com.github.spotbugs</groupId>
        <artifactId>spotbugs-maven-plugin</artifactId>
        <version>${spotbugs-maven-plugin.version}</version>
        <configuration>
          <xmlOutput>true</xmlOutput>
          <!-- Optional directory to put spotbugs xdoc xml report -->
          <xmlOutputDirectory>target/site</xmlOutputDirectory>
        </configuration>
      </plugin>
      <!--https://maven.apache.org/plugins/maven-pmd-plugin/ -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-pmd-plugin</artifactId>
        <version>${maven-pmd-plugin.version}</version>
        <configuration>
          <rulesets>
            <ruleset>whizbang/pmd-ruleset.xml</ruleset>
          </rulesets>
        </configuration>
        <reportSets>
          <reportSet>
            <reports>
              <report>pmd</report>
            </reports>
          </reportSet>
        </reportSets>
      </plugin>
      <!-- https://maven.apache.org/plugins/maven-checkstyle-plugin/ -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
        <version>${maven-checkstyle-plugin.version}</version>
        <configuration>
          <configLocation>whizbang/checkstyle.xml</configLocation>
        </configuration>
      </plugin>
    </plugins>
  </reporting>

  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <properties>
        <skipITs>false</skipITs>
        <quarkus.package.type>native</quarkus.package.type>
      </properties>
    </profile>

    <profile>
      <id>sonar</id>
      <activation>
        <activeByDefault>false</activeByDefault>
      </activation>
      <build>
        <plugins>
          <!-- Sonar Scanner -->
          <plugin>
            <groupId>org.sonarsource.scanner.maven</groupId>
            <artifactId>sonar-maven-plugin</artifactId>
            <version>${sonar-maven-plugin.version}</version>
            <executions>
              <execution>
                <id>sonar</id>
                <phase>verify</phase>
                <goals>
                  <goal>sonar</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>
wjglerum commented 1 year ago

Thanks @gaetanBloch! I tried it with your example, but no luck for me, still throws NullAway is not a valid checker name in dev mode after a hot reload.

Here's a minimal reproducer based on your example code-with-quarkus-nullaway.zip

Could you give that a try maybe?