maven-resources-plugin maven-site-plugin
Maven’s lifecycle defines when build tasks run, while plugins perform the actual work. Two common examples are maven-resources-plugin and maven-site-plugin. Although both deal with project files, they serve very different purposes: the resources plugin prepares assets for compilation, testing, and packaging, while the site plugin assembles project documentation into a browsable website.
A Java project usually contains more than source code. Applications may rely on properties files, XML mappings, templates, localization bundles, images, and other static assets. By default, maven-resources-plugin copies the contents of src/main/resources into target/classes, where they can be accessed by the application and included in the final JAR by maven-jar-plugin or maven-assembly-plugin.
The plugin provides two lifecycle-bound goals:
resources:resources, which runs during theprocess-resourcesphase and processes main resources.resources:testResources, which runs during theprocess-test-resourcesphase and copies test resources intotarget/test-classes.
Because these goals are bound by Maven’s default lifecycle, a basic build does not require an explicit plugin declaration.
Filtering build-time values
The plugin’s most useful feature is filtering. It replaces Maven properties in text resources before copying them to the output directory. A typical configuration might look like this:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
With filtering enabled, a resource such as application.properties can contain Maven expressions:
app.version=${project.version}
app.api-url=${app.api.url}
The value of app.api.url can be supplied by a Maven profile, command-line property, or another source supported by Maven’s property mechanism. For example:
<profiles>
<profile>
<id>integration</id>
<properties>
<app.api.url>https://integration.example.com</app.api.url>
</properties>
</profile>
</profiles>
Filtering is convenient, but it should be applied selectively. It works best for small text files whose values must be resolved at build time. Applying it indiscriminately to every resource can unintentionally modify application placeholders or corrupt binary files.
Separating filtered and unfiltered resources
Images, archives, fonts, and similar binary assets should normally be excluded from filtering. A safe approach is to divide the resource declarations by file type:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>images/**</exclude>
<exclude>archives/**</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>images/**</include>
<include>archives/**</include>
</includes>
</resource>
</resources>
This configuration ensures that text configuration files are processed while binary content is copied unchanged.
maven-site-plugin: Building Project Documentation
maven-site-plugin generates a static documentation website for a Maven project. The site can include project metadata taken from the POM, hand-written documentation stored under src/site, and reports generated by other Maven plugins.
Typical site content includes:
- Project name, description, licenses, and team information
- Source-code and issue-tracker links
- Developer and distribution documentation
- Javadoc or other API documentation
- Unit-test summaries
- Static-analysis results from tools such as Checkstyle or SpotBugs
- Dependency analysis and build-related reports
The plugin uses Maven’s Doxia engine to render source documents written in formats such as Markdown, APT, and XHTML. Markdown files are commonly placed in src/site/markdown, with index.md serving as the landing page.
Basic configuration
A site plugin declaration can be added to the build configuration:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<inputEncoding>UTF-8</inputEncoding>
<outputEncoding>UTF-8</outputEncoding>
<locales>en_US</locales>
</configuration>
</plugin>
</plugins>
</build>
The generated site is written to target/site. It can be created with:
mvn site
For local documentation work, the plugin can start a development server:
mvn site:run
The site is then available at http://localhost:8080, making it easy to review navigation, links, and formatting before publishing.
Site navigation and presentation can be customized through a site descriptor, usually located at src/site/site.xml. Projects with several documentation areas can define menu entries that point to different sections of the generated site.
Reporting and report selection
The site plugin does not independently perform every analysis shown on a site. Instead, it collects and renders output produced by reporting plugins. A project may therefore configure JUnit, Checkstyle, SpotBugs, dependency-analysis, or other reporting plugins and choose which results should appear.
Generating every possible report can make mvn site slow, especially in large repositories. Teams should review the <reporting> section and remove or disable reports that do not serve the project’s documentation needs. This produces a faster build and a more focused site.
Report publication can also be separated from generation:
mvn site
creates the local site, while:
mvn site:stage
prepares a deployment directory under target/staging. Actual deployment should be handled only after the required repository and distribution-management configuration has been reviewed.
Practical Recommendations
Keep resource filtering narrowly scoped
Enable filtering only for files that genuinely need build-time substitution. This reduces the risk of altering runtime placeholders or damaging binary content. It is also wise to avoid placing credentials directly in filtered resources, since the resulting values may be copied into build artifacts.
Pin plugin versions
Plugin versions inherited from Maven’s default lifecycle can differ between Maven installations. Explicitly declaring versions improves reproducibility and prevents unexpected changes in filtering behavior, encoding handling, or site output.
For projects that use several Maven plugins, versions can be centralized under <pluginManagement>:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.12.1</version>
</plugin>
</plugins>
</pluginManagement>
Use consistent encodings
Explicitly setting UTF-8 helps prevent garbled characters in filtered resources and generated documentation. Teams should also store source files in UTF-8 so that the build environment does not depend on platform-specific defaults.
Treat generated documentation as a build artifact
A useful site should be validated in continuous integration. Running mvn site during the build catches broken links, malformed documents, and failing report plugins before changes reach the default branch.
Together, maven-resources-plugin and maven-site-plugin cover two important parts of a Maven project: packaging the files an application needs at runtime and publishing the information that helps developers understand, maintain, and use it.