Skip to Content
Course content

118: Maven Plugins and Profiles

Click on the "Edit" button in the top corner of the screen to edit your slide content.

You've already got the hang of the basic Maven lifecycle, but in a real-world professional environment, you rarely have just one way of building your app. You've got your local machine, a QA server, and a production environment. They all need different settings—different database URLs, different logging levels, and different sets of checks. This is where Maven Profiles and Plugins come into play.

I'm going to show you how to set up a project that behaves differently depending on whether you're just hacking away locally or preparing a release for production. We'll build a simple configuration switcher and use a plugin to enforce code quality only during the production build.

Switching Environments with Profiles

First, let's talk about profiles. Think of a profile as a conditional set of configurations. I usually set up a dev profile for speed and a prod profile for rigor. In my pom.xml, I'll define these inside a <profiles> block. I'll use a property called db.url that changes based on the active profile.

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <db.url>jdbc:h2:mem:devdb</db.url>
            <log.level>DEBUG</log.level>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <db.url>jdbc:postgresql://prod-server:5432/myapp</db.url>
            <log.level>ERROR</log.level>
        </properties>
    </profile>
</profiles>

By setting activeByDefault to true for dev, I don't have to type anything extra when I'm just running tests locally. It just works.

Adding a Quality Gate with the Checkstyle Plugin

Now, I don't want my local build to fail just because I forgot a space before a curly brace—that's annoying when you're prototyping. But for a production build? That's non-negotiable. I'll use the maven-checkstyle-plugin. Instead of putting it in the global <build> section, I'll tuck it inside the prod profile.

<profile>
    <id>prod</id>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins>
                <artifactId>maven-checkstyle-plugin</artifactId>
                <version>3.3.1</version>
                <executions>
                    <execution>
                        <id>validate</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <consoleOutput>true</consoleOutput>
                    <failsOnError>true</failsOnError>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <db.url>jdbc:postgresql://prod-server:5432/myapp</db.url>
    </properties>
</profile>

The "Missing Property" Headache

Here is where I messed up. I tried to run mvn clean install -Pprod, and I noticed that while the Checkstyle plugin was running, my application was still picking up the dev database URL in some of my filtered resource files. I realized I had defined a default <db.url> in the main <properties> section of the POM, thinking it would be a safe fallback.

The problem is that Maven property precedence can be tricky. If you define a property in the global section and also in a profile, the profile should win—but I had a typo in the profile property name (I wrote <database.url> instead of <db.url>). Because the profile property didn't match the global one exactly, Maven just kept using the global dev value. I spent twenty minutes scratching my head before I noticed the extra "abase" in the name. Always double-check your property keys when profiles aren't behaving.

Triggering the Custom Build

To put this into action, you use the -P flag. If I want to run my "strict" production build, I'll run:

mvn clean install -Pprod

If I just run mvn clean install, Maven sees the activeByDefault flag on the dev profile. It skips Checkstyle and uses the H2 in-memory database. This separation of concerns keeps the developer experience fast while keeping the production pipeline safe.




📋 Practical Task

Implementing a QA Environment Profile for the Database Migrator

You are working on a project that has dev and prod profiles, but the team has requested a qa profile for the staging server. Your task is to modify the pom.xml to support this.

  • Create a new profile with the ID qa.
  • Inside the qa profile, set a property db.url to jdbc:postgresql://qa-server:5432/testdb.
  • Add the maven-antrun-plugin to the qa profile only. Configure it to execute a simple echo command: "Deploying to QA Environment..." during the package phase.
  • Ensure that the dev profile remains the default.

Verify your work by running mvn package -Pqa and ensuring the Antrun message appears in the console output, while running mvn package (without the flag) does not trigger the message.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.