Get up to speed with the core of Maven quickly, and then go beyond the foundations into the more powerful functionality of the build tool, such as profiles, scopes, multi-module projects and quite a bit more:
Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.
Get started with mocking and improve your application tests using our Mockito guide:
Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.
Get started with understanding multi-threaded applications with our Java Concurrency guide:
Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:
Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.
But these can also be overused and fall into some common pitfalls.
To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:
Get started with Spring and Spring Boot, through the Learn Spring course:
>> LEARN SPRINGExplore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:
Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.
I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.
You can explore the course here:
Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.
Get started with Spring Data JPA through the guided reference course:
Refactor Java code safely β and automatically β with OpenRewrite.
Refactoring big codebases by hand is slow, risky, and easy to put off. Thatβs where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.
Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions β one for newcomers and one for experienced users. Youβll see how recipes work, how to apply them across projects, and how to modernize code with confidence.
Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.
1. Overview
A Maven archetype is an abstraction of a kind of a project that can be instantiated into a concrete customized Maven project. In short, itβs a template project template from which other projects are created.
The main benefit of using archetypes is to standardize project development and to enable developers to easily follow best practices while bootstrapping their projects faster.
In this tutorial, weβll look at how to create a custom archetype and then how to use it to generate a Maven project through the maven-archetype-plugin.
2. Maven Archetype Descriptor
The Maven archetype descriptor is the heart of the archetype project. Itβs an XML file named archetype-metadata.xml and located in the META-INF/maven directory of the jar.
Itβs used to describe archetypesβ metadata:
<archetype-descriptor
...
name="custom-archetype">
<requiredProperties>
<requiredProperty key="foo">
<defaultValue>bar</defaultValue>
</requiredProperty>
</requiredProperties>
<fileSets>
<fileSet filtered="true" packaged="true">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
</fileSets>
<modules>
<module name="sub-module"></module>
</modules>
</archetype-descriptor>
The requiredProperties tag is used for providing properties during project generation. Thus, weβll be prompted to provide values for them, with the choice to accept the default value.
fileSets, on the other hand, are used to configure which resources will be copied into the concrete generated project. A filtered file means that placeholders will be substituted with provided values during the generation process.
And, by using packaged=βtrueβ in the fileSet, weβre saying that selected files will be added to the folder hierarchy specified by the package property.
If we want to generate a multi-module project, then the tag modules can help to configure all modules of the generated project.
Note that this file is about Archetype 2 and above. In the version 1.0.x, the file was just called archetype.xml and it had a different structure.
For more information, definitely have a look at the official Apache docs.
3. How to Create an Archetype
An archetype is a normal Maven project with the following extra content:
- src/main/resources/archetype-resources is the template from which resources are copied to the newly created project
- src/main/resources/META-INF/maven/archetype-metadata.xml: is the descriptor used to describe archetypesβ metadata
To create an archetype manually, we can start with a newly created Maven project and then we can add the resources mentioned above.
Or, we can generate it by using the archetype-maven-plugin, and then customize the content of the archetype-resources directory and archetype-metadata.xml file.
To generate the archetype, we can use:
mvn archetype:generate -B -DarchetypeArtifactId=maven-archetype-archetype \
-DarchetypeGroupId=maven-archetype \
-DgroupId=com.baeldung \
-DartifactId=test-archetype
We can also create the archetype from an existing Maven project:
mvn archetype:create-from-project
Itβs generated in target/generated-sources/archetype, ready to be used.
No matter how weβve created the archetype, weβll end up with the following structure:
archetype-root/
βββ pom.xml
βββ src
βββ main
βββ java
βββ resources
βββ archetype-resources
β βββ pom.xml
β βββ src
βββ META-INF
βββ maven
βββ archetype-metadata.xml
We can now start building our archetype by putting resources in the archetype-resources directory and configuring them in the archetype-metadata.xml file.
4. Building the Archetype
Now weβre ready to customize our archetype. For the highlight of this process, weβre going to showcase the creation of a simple Maven archetype for generating a RESTful application based on JAX-RS 2.1.
Letβs just call it maven-archetype.
4.1. Archetype Packaging
Letβs start by modifying the pom.xml of the archetype project located under the maven-archetype directory:
<packaging>maven-archetype</packaging>
This type of packaging is available thanks to the archetype-packaging extension:
<build>
<extensions>
<extension>
<groupId>org.apache.maven.archetype</groupId>
<artifactId>archetype-packaging</artifactId>
<version>3.0.1</version>
</extension>
</extensions>
<!--....-->
</build>
4.2. Adding the pom.xml
Letβs now create a pom.xml file located under the archetype-resources directory:
<project ...>
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>2.1.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
As we can see, groupId, artifactId and version are parameterized. They will be replaced during the creation of a new project from this archetype.
We can put everything needed by the generated project, like dependencies and plugins, in the pom.xml. Here, weβve added the JAX RS dependency as the archetype will be used for generating RESTful based application.
4.3. Adding Required Resources
Next, we can add some Java code for our application in archetype-resources/src/main/java.
A class for configuring JAX-RS application:
package ${package};
// import
@ApplicationPath("${app-path}")
public class AppConfig extends Application {
}
And a class for a ping resource:
@Path("ping")
public class PingResource{
//...
}
Finally, put the server configuration file, server.xml, in archetype-resources/src/main/config/liberty.
4.4. Configuring Metadata
After adding all needed resources, we can now configure which ones will be copied during generation through the archetype-metadata.xml file.
We can tell our archetype that we want all Java source files to be copied:
<archetype-descriptor
name="maven-archetype">
<!--...-->
<fileSets>
<fileSet filtered="true" packaged="true">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/config/liberty</directory>
<includes>
<include>server.xml</include>
</includes>
</fileSet>
</fileSets>
</archetype-descriptor>
Here, we want all Java files from src/main/java directory, and the server.xml file from src/main/config/liberty, to be copied.
4.5. Installing the Archetype
Now that weβve finished putting it all together, we can install the archetype by invoking this command:
mvn install
At this point, the archetype is registered in the file archetype-catalog.xml, located in Maven local repository, and therefore ready for use.
5. Using the Installed Archetype
The maven-archetype-plugin allows the user to create a Maven project through the generate goal and existing archetype. For more information on this plugin, you can visit the homepage.
This command uses this plugin to generate a Maven project from our archetype:
mvn archetype:generate -DarchetypeGroupId=com.baeldung.archetypes
-DarchetypeArtifactId=maven-archetype
-DarchetypeVersion=1.0-SNAPSHOT
-DgroupId=com.baeldung.restful
-DartifactId=cool-jaxrs-sample
-Dversion=1.0-SNAPSHOT
We should then pass the GAV of our archetype as arguments to the maven-archetype-plugin:generate goal. We can also pass the GAV of the concrete project that we want to generate, otherwise, we can provide them in interactive mode.
The concrete cool-jaxrs-sample generated project is therefore ready to run without any changes. So, we can run it by just invoking this command:
mvn package liberty:run
We can then access this URL:
http://localhost:9080/cool-jaxrs-sample/<app-path>/ping
6. Conclusion
In this article, weβve showcased how to build and use a Maven archetype.
Weβve demonstrated how to create the archetype and then how to configure the template resources through the archetype-metadata.xml file.
