DEV Community

khalil la
khalil la

Posted on

Spring Boot with Spotless and Git Pre-commit Hooks

This guide walks you through setting up automated code formatting and pre-commit checks in a Spring Boot Maven project, ensuring consistent code style across your team.

Table of Contents

Introduction

Having consistent code style across a project improves readability and maintainability. This guide combines three powerful tools:

  • Spotless: A code formatter that enforces style rules
  • Git Pre-commit Hooks: Automatically checks or formats code before commits
  • Maven: Integrates these tools into your build process

Prerequisites

  • Java 8 or higher
  • Maven 3.6.0 or higher
  • Git installed and initialized in your project
  • A Spring Boot project (or willingness to create one)

Step 1: Set Up a Spring Boot Project

If you don't already have a Spring Boot project, create one using Spring Initializr or with the following Maven command:

mvn archetype:generate -DgroupId=com.example -DartifactId=demo -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
Enter fullscreen mode Exit fullscreen mode

Make sure to initialize Git in your project directory:

git init
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure Spotless Maven Plugin

Add the Spotless Maven plugin to your pom.xml file in the <build><plugins> section:

<plugin>
    <groupId>com.diffplug.spotless</groupId>
    <artifactId>spotless-maven-plugin</artifactId>
    <version>2.40.0</version>
    <configuration>
        <java>
            <includes>
                <include>src/main/java/**/*.java</include>
                <include>src/test/java/**/*.java</include>
            </includes>
            <googleJavaFormat>
                <version>1.16.0</version>
                <style>GOOGLE</style>
            </googleJavaFormat>
            <removeUnusedImports />
            <importOrder>
                <order>java,javax,org,com,</order>
            </importOrder>
        </java>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>check</goal>
            </goals>
            <phase>compile</phase>
        </execution>
    </executions>
</plugin>
Enter fullscreen mode Exit fullscreen mode

This configuration:

  • Uses Google's Java code style
  • Removes unused imports
  • Organizes imports in a specific order
  • Checks formatting during compilation

Step 3: Install Git Hooks with Maven

Add the Git Build Hook Maven plugin to manage Git hooks:

<plugin>
    <groupId>com.rudikershaw.gitbuildhook</groupId>
    <artifactId>git-build-hook-maven-plugin</artifactId>
    <version>3.4.1</version>
    <configuration>
        <preCommit>mvn spotless:apply</preCommit>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>install</goal>
            </goals>
            <phase>initialize</phase>
        </execution>
    </executions>
</plugin>
Enter fullscreen mode Exit fullscreen mode

This plugin:

  • Installs Git hooks during the initialize phase
  • Sets up a pre-commit hook that runs mvn spotless:apply before each commit

Step 4: Adding Git Commit ID Plugin

Add the Git Commit ID plugin to include Git information in your build:

<plugin>
    <groupId>io.github.git-commit-id</groupId>
    <artifactId>git-commit-id-maven-plugin</artifactId>
    <version>6.0.0</version>
    <executions>
        <execution>
            <id>get-the-git-infos</id>
            <goals>
                <goal>revision</goal>
            </goals>
            <phase>initialize</phase>
        </execution>
    </executions>
    <configuration>
        <generateGitPropertiesFile>true</generateGitPropertiesFile>
        <generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
        <includeOnlyProperties>
            <includeOnlyProperty>^git.branch$</includeOnlyProperty>
            <includeOnlyProperty>^git.commit.id$</includeOnlyProperty>
            <includeOnlyProperty>^git.commit.time$</includeOnlyProperty>
        </includeOnlyProperties>
    </configuration>
</plugin>
Enter fullscreen mode Exit fullscreen mode

This adds Git metadata to your build, which can be useful for tracking versions and build information.

Step 5: Full POM Example

Here's a complete pom.xml example for a Spring Boot project with all these configurations:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.3</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo Spring Boot project with Spotless and Git hooks</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <!-- Spotless Plugin -->
            <plugin>
                <groupId>com.diffplug.spotless</groupId>
                <artifactId>spotless-maven-plugin</artifactId>
                <version>2.40.0</version>
                <configuration>
                    <java>
                        <includes>
                            <include>src/main/java/**/*.java</include>
                            <include>src/test/java/**/*.java</include>
                        </includes>
                        <googleJavaFormat>
                            <version>1.16.0</version>
                            <style>GOOGLE</style>
                        </googleJavaFormat>
                        <removeUnusedImports />
                        <importOrder>
                            <order>java,javax,org,com,</order>
                        </importOrder>
                    </java>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>check</goal>
                        </goals>
                        <phase>compile</phase>
                    </execution>
                </executions>
            </plugin>

            <!-- Git Commit ID Plugin -->
            <plugin>
                <groupId>io.github.git-commit-id</groupId>
                <artifactId>git-commit-id-maven-plugin</artifactId>
                <version>6.0.0</version>
                <executions>
                    <execution>
                        <id>get-the-git-infos</id>
                        <goals>
                            <goal>revision</goal>
                        </goals>
                        <phase>initialize</phase>
                    </execution>
                </executions>
                <configuration>
                    <generateGitPropertiesFile>true</generateGitPropertiesFile>
                    <generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
                    <includeOnlyProperties>
                        <includeOnlyProperty>^git.branch$</includeOnlyProperty>
                        <includeOnlyProperty>^git.commit.id$</includeOnlyProperty>
                        <includeOnlyProperty>^git.commit.time$</includeOnlyProperty>
                    </includeOnlyProperties>
                </configuration>
            </plugin>

            <!-- Git Hook Plugin -->
            <plugin>
                <groupId>com.rudikershaw.gitbuildhook</groupId>
                <artifactId>git-build-hook-maven-plugin</artifactId>
                <version>3.4.1</version>
                <configuration>
                    <preCommit>mvn spotless:apply</preCommit>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>install</goal>
                        </goals>
                        <phase>initialize</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
Enter fullscreen mode Exit fullscreen mode

Step 6: Using the Configuration

After adding these configurations to your pom.xml:

  1. Install the Git hooks:
mvn initialize
Enter fullscreen mode Exit fullscreen mode
  1. Verify the pre-commit hook is installed:
cat .git/hooks/pre-commit
Enter fullscreen mode Exit fullscreen mode

You should see something that includes the command mvn spotless:apply.

  1. Now when you try to commit code:

    • The pre-commit hook will automatically run mvn spotless:apply
    • This will format your code according to the configured style
    • Then the commit will proceed
  2. Manual Spotless commands:

    • Check for formatting issues without changing files: mvn spotless:check
    • Apply formatting to all files: mvn spotless:apply

Step 7: Customization Options

Alternative Formatting Styles

If you prefer the Eclipse formatter instead of Google's style:

<java>
    <eclipse>
        <file>${project.basedir}/eclipse-formatter.xml</file>
    </eclipse>
</java>
Enter fullscreen mode Exit fullscreen mode

You'll need to provide an Eclipse formatter configuration file.

Formatting Other File Types

Add formatters for additional file types:

<configuration>
    <java>
        <!-- Java configuration as before -->
    </java>
    <xml>
        <includes>
            <include>src/main/**/*.xml</include>
            <include>pom.xml</include>
        </includes>
    </xml>
    <yaml>
        <includes>
            <include>src/main/resources/**/*.yml</include>
            <include>src/main/resources/**/*.yaml</include>
        </includes>
    </yaml>
</configuration>
Enter fullscreen mode Exit fullscreen mode

Custom Import Order

Customize the import order to match your team's preferences:

<importOrder>
    <order>com.yourcompany,com,org,javax,java,\#</order>
</importOrder>
Enter fullscreen mode Exit fullscreen mode

Different Pre-commit Actions

To run both formatting check and tests in pre-commit:

<configuration>
    <preCommit>mvn spotless:apply test</preCommit>
</configuration>
Enter fullscreen mode Exit fullscreen mode

Troubleshooting

Pre-commit Hook Not Running

If the pre-commit hook doesn't run automatically:

  1. Check that the hook file has execution permissions:
   chmod +x .git/hooks/pre-commit
Enter fullscreen mode Exit fullscreen mode
  1. Verify Git hooks are not being ignored:
   git config core.hooksPath
Enter fullscreen mode Exit fullscreen mode

It should return .git/hooks or be empty.

Spotless Fails to Apply Formatting

If Spotless fails with formatting errors:

  1. Run mvn spotless:apply manually to see detailed error messages
  2. Check if your code has syntax errors that prevent formatting
  3. Ensure you're using a compatible Java version for the configured formatter

Git Commit ID Plugin Fails

If the Git Commit ID plugin fails:

  1. Ensure your project is a Git repository (git init)
  2. Make at least one initial commit before running the plugin
  3. Check if Git is properly installed and accessible

For more advanced options and configurations, refer to the official documentation:

Heroku

Amplify your impact where it matters most — building exceptional apps.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

Image of PulumiUP 2025

Let's talk about the current state of cloud and IaC, platform engineering, and security.

Dive into the stories and experiences of innovators and experts, from Startup Founders to Industry Leaders at PulumiUP 2025.

Register Now

👋 Kindness is contagious

Please express your appreciation ❤️ or leave a nice comment if you found this helpful!

Understood!