Skip to content

Instantly share code, notes, and snippets.

@sandeepkv93
Last active January 29, 2025 20:19
Show Gist options
  • Save sandeepkv93/51db90f0e288cf21ca7ff34aa143d828 to your computer and use it in GitHub Desktop.
Save sandeepkv93/51db90f0e288cf21ca7ff34aa143d828 to your computer and use it in GitHub Desktop.
Automated Java Code Formatting with Maven using google-java-format

Automated Java Code Formatting with Maven using google-java-format

This guide explains how to set up automated code formatting in a Java Maven project using Google's Java code formatter via the fmt-maven-plugin.

Overview

The setup combines two key components:

  • Google Java Format (google-java-format): Google's Java code formatter that enforces Google Java Style
  • Spotify's fmt-maven-plugin: A Maven plugin that integrates google-java-format into the Maven build lifecycle

Prerequisites

  • Maven 3.8.0 or higher
  • Java 8 or higher
  • A Maven-based Java project

Implementation

1. Add Version Properties

In your pom.xml, define the versions for both the formatter and the Maven plugin:

<properties>
    <google-java-format.version>1.17.0</google-java-format.version>
    <fmt-maven-plugin.version>2.25</fmt-maven-plugin.version>
</properties>

2. Configure the Format Maven Plugin

Add the following plugin configuration to your pom.xml in the <build><plugins> section:

<plugin>
    <groupId>com.spotify.fmt</groupId>
    <artifactId>fmt-maven-plugin</artifactId>
    <version>${fmt-maven-plugin.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>format</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
        <testSourceDirectory>${project.build.testSourceDirectory}</testSourceDirectory>
        <verbose>true</verbose>
        <filesNamePattern>.*\.java</filesNamePattern>
        <skipSortingImports>false</skipSortingImports>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>com.google.googlejavaformat</groupId>
            <artifactId>google-java-format</artifactId>
            <version>${google-java-format.version}</version>
        </dependency>
    </dependencies>
</plugin>

Configuration Options Explained

  • sourceDirectory: Directory containing the main source files
  • testSourceDirectory: Directory containing the test source files
  • verbose: Enables detailed output during formatting
  • filesNamePattern: Regular expression to match files for formatting
  • skipSortingImports: Controls whether import statements should be sorted

Usage

Format Code During Build

The plugin automatically runs during the Maven build process. To manually format your code:

mvn fmt:format

Check Format Without Modifying

To verify if code is properly formatted without making changes:

mvn fmt:check

IDE Integration

IntelliJ IDEA

  1. Install the "google-java-format" plugin
  2. Enable the plugin in Settings → Other Settings → google-java-format Settings
  3. Configure the code style:
    • Settings → Editor → Code Style → Java
    • Import the Google Style scheme

Eclipse

  1. Install the "google-java-format" plugin from the Eclipse Marketplace
  2. Configure formatting preferences to use Google Style

Best Practices

  1. Pre-commit Hooks: Set up git pre-commit hooks to ensure code is formatted before committing:

    #!/bin/sh
    mvn fmt:format
    git add .
  2. CI Integration: Add format checking to your CI pipeline:

    - name: Check Code Format
      run: mvn fmt:check
  3. Team Standards: Document the formatting setup in your project's README

    • Include installation steps for IDE plugins
    • Document any custom configurations
    • Explain the enforcement process

Troubleshooting

Common Issues

  1. Format Conflicts with IDE

    • Solution: Disable IDE's built-in formatter
    • Use only google-java-format plugin
  2. Build Failures Due to Format

    • Run mvn fmt:format before committing
    • Check IDE settings for conflicting formatters
  3. Version Compatibility

    • Ensure Java version compatibility
    • Check for plugin version conflicts

Notes

  • The formatter enforces Google Java Style Guide rules
  • Formatting is non-negotiable and consistent across all environments
  • Changes are automatically applied during the Maven build process
  • The plugin supports both main and test source directories
  • Import sorting is handled automatically unless explicitly disabled

Using Plugin Management

When working with multi-module Maven projects or when you want to centralize plugin configurations, you can use the <pluginManagement> section instead of directly declaring plugins. This approach is particularly useful for:

  • Ensuring consistent plugin versions across modules
  • Centralizing plugin configurations
  • Making plugin management more maintainable

Basic Setup with Plugin Management

Add the following configuration in your parent pom.xml:

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>com.spotify.fmt</groupId>
                <artifactId>fmt-maven-plugin</artifactId>
                <version>${fmt-maven-plugin.version}</version>
                <configuration>
                    <sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
                    <testSourceDirectory>${project.build.testSourceDirectory}</testSourceDirectory>
                    <verbose>true</verbose>
                    <filesNamePattern>.*\.java</filesNamePattern>
                    <skipSortingImports>false</skipSortingImports>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>com.google.googlejavaformat</groupId>
                        <artifactId>google-java-format</artifactId>
                        <version>${google-java-format.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

Child Module Configuration

In your child modules, you can then simply reference the plugin:

<build>
    <plugins>
        <plugin>
            <groupId>com.spotify.fmt</groupId>
            <artifactId>fmt-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>format</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Additional Plugin Management Benefits

  1. Version Control

    • Define plugin versions once in the parent POM
    • Child modules inherit the version automatically
    • Easier version updates across all modules
  2. Configuration Inheritance

    • Child modules can inherit the complete configuration
    • Override specific configuration elements when needed
    • Maintain consistency while allowing flexibility
  3. Execution Control

    <!-- In child module -->
    <build>
        <plugins>
            <plugin>
                <groupId>com.spotify.fmt</groupId>
                <artifactId>fmt-maven-plugin</artifactId>
                <!-- Override specific configuration -->
                <configuration>
                    <verbose>false</verbose>
                    <skipSortingImports>true</skipSortingImports>
                </configuration>
            </plugin>
        </plugins>
    </build>

Best Practices for Plugin Management

  1. Version Properties

    • Define all plugin versions as properties in the parent POM
    • Use property references in pluginManagement
    • Easier version management and updates
  2. Documentation

    • Comment complex configurations
    • Explain why certain settings are used
    • Document any module-specific overrides
  3. Module Organization

    parent-project/
    ├── pom.xml (with pluginManagement)
    ├── module1/
    │   └── pom.xml (minimal plugin config)
    ├── module2/
    │   └── pom.xml (minimal plugin config)
    └── module3/
        └── pom.xml (minimal plugin config)
    

Advanced Configuration

Custom Format Rules

While google-java-format is opinionated, you can still configure certain aspects:

<configuration>
    <style>AOSP</style> <!-- Use Android Open Source Project style -->
    <formatSplitStatements>false</formatSplitStatements>
    <formatJavadoc>true</formatJavadoc>
    <fixImports>true</fixImports>
</configuration>

Conditional Formatting

You can skip formatting based on conditions:

<configuration>
    <skip>${format.skip}</skip>
    <skipSourceDirectory>${skip.sources}</skipSourceDirectory>
    <skipTestSourceDirectory>${skip.tests}</skipTestSourceDirectory>
</configuration>

Maven Profile Integration

Create profiles for different formatting scenarios:

<profiles>
    <profile>
        <id>strict-format</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>com.spotify.fmt</groupId>
                    <artifactId>fmt-maven-plugin</artifactId>
                    <configuration>
                        <verbose>true</verbose>
                        <failOnError>true</failOnError>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment