The framework uses three main modules:

  • API: the runtime API, it is the runtime API, mainly resolution/look-up oriented

  • Build API: it is the API only required at build time, it is intended to be used to trigger the generation of the runtime classes using processor module,

  • Processor: it contains the magic generating most of the runtime and making the framework efficient and light.

Therefore the project will generally get the api in scope compile, the build api in scope provided or optional and the processor either in scope provided/optional or just defined as an annotation processor in your compiler configuration.

Important
the generation process assumes the annotation processor is aware of all classes, depending the tools you generate you can need to disable incremental compilation as of today to ensure all classes are seen by the generator.

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+BR 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).