This page details Setup your project.

Maven

Simplest

The simplest is to just add the API (scope compile) and processor (scope provided):

<dependencies>
  <dependency>
    <groupId>io.yupiik.fusion</groupId>
    <artifactId>fusion-api</artifactId>
    <version>${fusion.version}</version>
  </dependency>
  <dependency>
    <groupId>io.yupiik.fusion</groupId>
    <artifactId>fusion-processor</artifactId>
    <version>${fusion.version}</version>
    <scope>provided</scope>
  </dependency>
</dependencies>
TIP

if can be sane to compile your project with maven (mvn compile or mvn process-classes) instead of relying on your IDE. This is indeed a general rule but, in this case, will enable to avoid the pitfalls of a fake incremental compilation (compiling only a few source files using the precompiled project output). This last case can lead to missing bean, you can obviously delete the target folder of your project to force your IDE to recompile but it is saner to just rely on a properly compile phase.

Java >=21

Java 21 starts to warn when you use annotation processors autodiscovery. Future java versions will even disable it by default.

For such version, you must explicitly enable the annotation processing. One option to do that is to use this maven-compiler-plugin configuration:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.11.0</version>
  <executions>
    <execution>
      <id>default-process-annotations</id>
      <phase>generate-sources</phase>
      <goals>
        <goal>compile</goal>
      </goals>
      <configuration>
        <proc>only</proc>
        <useIncrementalCompilation>true</useIncrementalCompilation>
      </configuration>
    </execution>
    <execution>
      <id>test-process-annotations</id>
      <phase>generate-test-sources</phase>
      <goals>
        <goal>testCompile</goal>
      </goals>
      <configuration>
        <proc>only</proc>
        <useIncrementalCompilation>true</useIncrementalCompilation>
      </configuration>
    </execution>
  </executions>
  <configuration>
    <proc>none</proc>
    <source>21</source>
    <target>21</target>
    <release>21</release>
    <encoding>UTF-8</encoding>
    <useIncrementalCompilation>false</useIncrementalCompilation>
    <compilerArgs>
      <compilerArg>-parameters</compilerArg>
    </compilerArgs>
    <annotationProcessors>
      <annotationProcessor>io.yupiik.fusion.framework.processor.FusionProcessor</annotationProcessor>
    </annotationProcessors>
  </configuration>
</plugin>

IDE/Jetbrains Idea

Until you configure IDEA to use maven to compile, it can happen it compiles a single source (at least not the whole module properly like Maven by default) so the output can miss some beans. If it happens (java: java.lang.IllegalArgumentException: Unsupported type: 'com.superbiz.MyJsonModel', known models: [....] at compile time or NoClassDefFoundError/No bean matching type '...' at test/runtime for example), then just Rebuild the project, command is in Build menu (shortcut: Alt+B -> R by default).

Ultimately just drop the target/out folder if it is not about adding a file but more about removing a file (incremental support of such a change is not great as of today - but this is not specific to this project ;)).

Use ECJ compiler (Eclipse)

For ECJ to work you need to ensure the argument -sourcepath is set in compiler configuration and import plexus-compiler-eclipse (Maven):

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.10.1</version>
  <configuration>
    <compilerId>eclipse</compilerId>
    <compilerArguments>
      <sourcepath>${project.basedir}/src/main/java</sourcepath>
    </compilerArguments>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-compiler-eclipse</artifactId>
      <version>2.12.1</version>
    </dependency>
  </dependencies>
</plugin>

Do not expose processor in code completion

A more advanced option would be to define the api in scope compile, the build API in scope provided and the processor only in maven-compiler-plugin.

This option is more complex in terms of configuration but has the advantage to not expose the processor in the IDE (completion).

Here is what it can look like:

<project>
  <dependencies>
    <dependency>
      <groupId>io.yupiik.fusion</groupId>
      <artifactId>fusion-api</artifactId>
      <version>${fusion.version}</version>
    </dependency>
    <dependency>
      <groupId>io.yupiik.fusion</groupId>
      <artifactId>fusion-build-api</artifactId>
      <version>${fusion.version}</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.10.1</version>
        <configuration>
          <annotationProcessorPaths>
            <annotationProcessorPath>
              <groupId>io.yupiik.fusion</groupId>
              <artifactId>fusion-processor</artifactId>
              <version>${fusion.version}</version>
            </annotationProcessorPath>
          </annotationProcessorPaths>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
IMPORTANT

disabling the incremental compilation there is generally a good idea, in particular on CI but not having the processor in provided scope will make your IDE no more able to generate properly classes in general. So a better option can be to stick to previous dependencies only option (by default maven recompiles properly the module - don't set <useIncrementalCompilation>false</useIncrementalCompilation> it means do not use incremental compilation).

Annotation processor options

The fusion annotation processor (FusionProcessor) accepts a set of compile-time options you can pass through -A<key> (maven-compiler-plugin compilerArgs or annotationProcessorOptions). They let you tune what is generated:

Option Purpose

fusion.skipNotes

Disable the generated @Note on generated code.

fusion.workdir

Enforces the work directory of the generator.

fusion.generateModule

Generate the FusionModule implementation (true by default when possible).

fusion.moduleAppend

Deprecated compatibility option, ignored.

fusion.moduleFqn

Fully qualified name of the generated module.

fusion.generateBeanForCliCommands

Generate beans for @Command beans.

fusion.generateBeanForHttpEndpoints

Generate beans for @HttpMatcher endpoints.

fusion.generateBeanForJsonRpcEndpoints

Generate beans for @JsonRpc methods.

fusion.generateBeanForPersistenceEntities

Generate persistence entity models.

fusion.generatePartialOpenRPC

Generate the partial OpenRPC documents.

fusion.generateJsonSchemas

Generate the JSON schemas (META-INF/fusion/json/schemas.json).

fusion.generateBeanForJsonCodec

Generate the JSON codecs for @JsonModel records.

fusion.generateConfigurationDocMetadata

Generate the configuration documentation metadata.

fusion.generateBeanForRootConfiguration

Generate the configuration beans for @RootConfiguration records.

fusion.generateNativeImage

Generate GraalVM native-image reachability metadata.

fusion.skipLoadingModules

Skip loading external fusion modules during generation.

fusion.debug.timeTracking

Log the generation time of each phase.