Create New Axon Framework Multi-Project

For our sample application, we will create a multi-module maven project containing only two modules: a core-api module containing the API definition and messages used within the application and a rental module containing the business logic for our bike rental application.

Project structure

We will design our rental module as a modular monolith, which means that we will keep a single project, but with the logic components decoupled so that it is easy to split the module into different pieces later.

First, we need to create a new project and configure the AxonFramework dependencies that will help us focus on the business code.

We will create a maven project with the following structure:

Bike Rental demo application structure
📒 bike-rental (1)
  📒 core-api (2)
    📂 src
      📂 main
        📂 java
           📦 io.axoniq.demo.bikerental.coreapi (3)
    📄 pom.xml (4)
  📒 rental (5)
    📂 src
      📂 main
        📂 java
           📦 io.axoniq.demo.bikerental.rental (6)
    📄 pom.xml (7)
  📄 pom.xml (8)
1 The bike-rental root project is the parent project that will contain all the modules from our application. This root project will define org.springframework.boot:spring-boot-starter-parent as its parent to configure SpringBoot support for all the modules.
2 The core-api project will contain the API and definition of the messages used to communicate the different modules.
3 The io.axoniq.demo.bikerental.coreapi is the package where we will place our classes with the definition of Commands, Events, and Queries exchanged between different modules.
4 The pom.xml maven descriptor contains the dependency declaration for the core-api project and links to bike-rental as its parent project.
5 The rental module will be our starting point to place the business logic of our application.
6 The io.axoniq.demo.bikerental.rental package is where we will add the code for our application.
7 The pom.xml maven descriptor will include the dependencies required for the rental module. It also declares bike-rental as its parent and inherits any dependency declaration from that project.
8 Finally, the pom.xml maven descriptor at the root bike-rental project keeps the common dependency definition inherited in all the submodules. It also keeps the list of <modules> that form part of the project.

If you are already experienced with Maven and/or your IDE, you can just create a multi-maven project with the structure described here and move to the next step of this tutorial to configure Axon Framework in your project.

If you prefer to follow step-by-step instructions to create the project, keep reading through the following sections in this step:

Create the root project

We will use Maven as the build tool for this project. We aim to create a multi-module project that allows us to deploy each module independently later when -and if- our application reaches the point at which we need to split it and scale out.

We will start by creating the root project containing the different modules or subprojects. This type corresponds to a maven project with the packaging property set to pom.

You can create the project from your console terminal with the following maven command:

 mvn archetype:generate \
  -DarchetypeGroupId=org.codehaus.mojo.archetypes \
  -DarchetypeArtifactId=pom-root \
  -DarchetypeVersion=RELEASE \
  -DgroupId=io.axoniq.demo.bikerental \
  -DartifactId=bike-rental \
  -Dversion=0.0.1-SNAPSHOT \
  -DinteractiveMode=false

Maven will create a bike-rental folder with a maven project descriptor file: pom.xml. You can import the project into your favorite IDE.

Alternatively, you can use your preferred IDE to create the project, making sure to set the following project properties:

archetypeGroupId

org.codehaus.mojo.archetypes

archetypeArtifactId

pom-root

archetypeVersion

RELEASE

groupId

io.axoniq.demo.bikerental

artifactId

bike-rental

version

0.0.1-SNAPSHOT

To configure Java 21 for our project, add these properties to the pom.xml file:

    <properties>
		<maven.compiler.source>21</maven.compiler.source>
		<maven.compiler.target>21</maven.compiler.target>
		<java.version>21</java.version>
    </properties>

Configuring SpringBoot

Now that we have our root project, we need to configure it to use SpringBoot. We can configure the SpringBoot dependencies in our project in two ways: the first one is by adding them under the <dependencyManagement> section of the root pom.xml file.

Alternatively, we can make our root project depend on `org.springframework.boot:spring-boot-starter-parent', which already defines all the dependencies needed to use SpringBoot in our projects.

We will use the second option. Open your pom.xml and add the following snippet right before the <groupId> tag:

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.2.1</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

Create the project modules

We will start by creating a main module for our bike rental application. This module will contain the business logic.

Our goal with AxonIQ technologies is to focus on a single application and avoid unnecessary complexity by dealing with multiple modules immediately. However, we aim to build our module in a way that allows for easy evolution into different modules. This design is what we call a modular monolith.

Creating the main rental module

Our main module will be the rental module. To create it, you can use your IDE to add a new module, or you can use the following maven command from the root bike-rental folder:

 mvn archetype:generate -DgroupId=io.axoniq.demo.bikerental -DartifactId=rental -Dpackage=io.axoniq.demo.bikerental.rental -DinteractiveMode=false

After running the mvn command you will see a new rental directory with a rental/pom.xml file, which declares the project as a sub-module of the root project:

rental/pom.xml
    <parent>
        <groupId>io.axoniq.demo.bikerental</groupId>
        <artifactId>bike-rental</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>rental</artifactId>

At the same time, the execution of the mvn command also modified the maven project descriptor of the root project to include the new module:

/pom.xml
	<modules>
		<module>rental</module>
	</modules>

Your IDE should now show the new project as a submodule.

If the IDE does not detect the new module, you may have to refresh the project structure and reload the Maven projects in your IDE.

Creating the core-api subproject

Although we are going to code our business logic in a single rental module, we also have already mentioned that we want to be able to split our project into different modules when we need to evolve into multiple modules (or microservices).

So, we are going to have a module in which we will include the definitions of the messages and classes that are used to communicate the different modules. We will name this project as core-api.

To create the core-api submodule, use your IDE to create a new Module (make sure you create it using the root project as the parent), or you can use the following maven command from the root project’s folder:

 mvn archetype:generate -DgroupId=io.axoniq.demo.bikerental -DartifactId=core-api -Dpackage=io.axoniq.demo.bikerental.coreapi -DinteractiveMode=false

After executing the command, you should see a new core-api project with a pom.xml file declaring the root project as the parent:

/core-api/pom.xml
    <parent>
        <artifactId>bike-rental</artifactId>
        <groupId>io.axoniq.demo.bikerental</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

And the maven descriptor in the root project now should also include the core-api as a module:

/pom.xml
	<modules>
		<module>rental</module>
		<module>core-api</module>
	</modules>

Your IDE should recognize the two sub-projects as modules.

If the IDE does not detect the new module, you may have to refresh the project structure and reload the Maven projects in your IDE.

Add dependencies for the main rental module

As the last step in creating the multi-module structure for our project, we will declare that the main rental module will use the core-api module.

To do that, declare the following dependency in the maven descriptor file for the rental module:

rental/pom.xml
    <dependencies>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>core-api</artifactId>
            <version>${project.version}</version>
        </dependency>

    </dependencies>

After completing this last step your project should have the structure that we described in the Project Structure section at the begining of this step.

Once that we have our project created, in the next step, we will learn how to bootstrap Axon Framework in our project.