How do I configure Maven Surefire for JUnit tests?

To configure Maven Surefire for running JUnit tests, add the Maven Surefire Plugin to the <build> section of your pom.xml.

For modern JUnit 5 tests, you typically need:

  1. A JUnit 5 dependency
  2. The Maven Surefire Plugin
  3. Test classes named using Maven’s default test naming patterns

1. Add JUnit 5 Dependency

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.13.4</version>
        <scope>test</scope>
    </dependency>
</dependencies>

2. Configure Maven Surefire Plugin

Add this inside your pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.5.3</version>
        </plugin>
    </plugins>
</build>

A complete minimal Maven setup looks like this:

<project>
    <!-- project coordinates omitted -->

    <properties>
        <maven.compiler.release>25</maven.compiler.release>
        <junit.jupiter.version>5.13.4</junit.jupiter.version>
        <maven.surefire.version>3.5.3</maven.surefire.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit.jupiter.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.version}</version>
            </plugin>
        </plugins>
    </build>
</project>

3. Use Standard Test Class Names

By default, Surefire runs tests whose names match patterns like:

**/Test*.java
**/*Test.java
**/*Tests.java
**/*TestCase.java

For example:

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class CalculatorTest {

    @Test
    void shouldAddTwoNumbers() {
        int result = 2 + 3;

        assertEquals(5, result);
    }
}

4. Run the Tests

From the project directory, run:

mvn test

Maven will compile your test code and run tests using Surefire.

5. Optional: Include or Exclude Specific Tests

You can customize which tests Surefire runs:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.5.3</version>
    <configuration>
        <includes>
            <include>**/*Test.java</include>
            <include>**/*Tests.java</include>
        </includes>
        <excludes>
            <exclude>**/*IntegrationTest.java</exclude>
        </excludes>
    </configuration>
</plugin>

6. Optional: Run Tests by Tag

If you use JUnit 5 tags:

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

class PaymentServiceTest {

    @Test
    @Tag("fast")
    void shouldProcessPayment() {
        // test code
    }
}

Configure Surefire like this:

<configuration>
    <groups>fast</groups>
</configuration>

Or run from the command line:

mvn test -Dgroups=fast

Summary

For JUnit 5, the essential Maven Surefire configuration is:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.13.4</version>
    <scope>test</scope>
</dependency>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.5.3</version>
</plugin>

Then run:

mvn test

How do I add JUnit to a Maven project?

To add JUnit to a Maven project, you add the JUnit dependency to your project’s pom.xml, create test classes under src/test/java, and run the tests with Maven.

1. Add JUnit to pom.xml

For modern Java projects, use JUnit 5.

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.13.4</version>
        <scope>test</scope>
    </dependency>
</dependencies>

If your pom.xml already has a <dependencies> section, add only the <dependency> block inside it.

2. Configure Maven Surefire Plugin

JUnit tests are usually run by the Maven Surefire Plugin. Add this inside the <build> section of your pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.5.3</version>
        </plugin>
    </plugins>
</build>

If your project already has a <build> or <plugins> section, merge the plugin into the existing structure instead of duplicating it.

3. Create a Test Class

Maven expects test classes to be placed under:

src/test/java

Example project structure:

my-project
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── org
    │           └── kodejava
    │               └── Calculator.java
    └── test
        └── java
            └── org
                └── kodejava
                    └── CalculatorTest.java

Example class to test:

package org.kodejava;

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}

Example JUnit 5 test:

package org.kodejava;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class CalculatorTest {

    @Test
    void addShouldReturnSum() {
        Calculator calculator = new Calculator();

        int result = calculator.add(2, 3);

        assertEquals(5, result);
    }
}

4. Run the Tests

From the project directory, run:

mvn test

Maven will compile your code, compile your tests, and run any matching test classes.

Common test class naming patterns include:

*Test.java
*Tests.java
*TestCase.java

Complete pom.xml Example

<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>

    <groupId>org.kodejava</groupId>
    <artifactId>junit-maven-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.release>25</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.13.4</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.3</version>
            </plugin>
        </plugins>
    </build>

</project>

That’s it — after adding the dependency and plugin configuration, you can start writing JUnit tests and run them with mvn test.

A Comprehensive Guide to Setting Up Apache Maven

In this guide, you’ll learn everything you need to know about Apache Maven—from what it is to how to configure it across different operating systems.


What is Apache Maven?

In simple terms, Maven is a powerful build and project management tool primarily used by Java developers. Compared to older build systems like Apache Ant, Maven provides a standardized way to manage builds, dependencies, and project lifecycles.

Key Features of Maven:

  • Simplifies the build process.
  • Ensures consistency with a uniform build system.
  • Manages project dependencies through a central or local repository.
  • Provides quality project information.
  • Follows development best practices.
  • Allows for smooth migration to new features.

Now, let’s dive into how to install and configure Maven on your system.


Step 1: Downloading Apache Maven

  1. Visit the official Apache Maven Download page.
  2. Download the binary archive matching your operating system:
    • .zip for Windows
    • .tar.gz for Linux/macOS
  3. Extract the archived files to a directory of your choice:
    • On Windows, you might extract to: C:\Apache\apache-maven-<version>
    • On Linux/macOS, extract it to: /opt/apache-maven-<version>

Step 2: Configuring Environment Variables

After downloading Maven, the next step is to configure your environment so that Maven can be accessed from your terminal or command prompt.

On Windows:

  1. Open System Properties:
    • Right-click on “This PC” → select Properties → click Advanced System Settings → select Environment Variables.
  2. Add the following system variables:
    • M2_HOME: Set this to the Maven installation directory (e.g., C:\Apache\apache-maven-<version>).
    • JAVA_HOME: Set this to your JDK installation directory (e.g., C:\Program Files\Java\jdk-<version>).
  3. Add M2_HOME\bin to your PATH variable:
    • Locate and edit the PATH variable in the Environment Variables list.
    • Append: ;%M2_HOME%\bin

On Linux/macOS:

  1. Open your shell profile configuration file. This depends on the shell you’re using:
    • For bash: ~/.bashrc or ~/.bash_profile
    • For zsh (default on macOS): ~/.zshrc
  2. Add the following lines to configure Maven and Java:
    export M2_HOME=/opt/apache-maven-<version>
    export PATH=$M2_HOME/bin:$PATH
    export JAVA_HOME=/path/to/your/jdk
    

    Example:

    export M2_HOME=/opt/apache-maven-3.9.5
    export PATH=$M2_HOME/bin:$PATH
    export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
    
  3. Reload the configuration:
    source ~/.bashrc    # For bash users
    source ~/.zshrc     # For zsh users
    

Step 3: Verifying the Installation

Now that Maven is installed and configured, it’s time to check if it works correctly.

  1. Open a terminal or command prompt.
  2. Run the following command:
    mvn -version
    
  3. You should see output similar to this:
    Apache Maven 3.x.x (...)
    Maven home: <Maven installation path>
    Java version: <your JDK version>, vendor: Oracle Corporation
    Java home: <JDK path>
    

Additional Installation Options

Using a Package Manager (Optional):

If you’re on Linux or macOS, you may install Maven using a package manager. Note that these methods may not always install the latest version.

  1. Linux (Ubuntu/Debian):
    sudo apt update
    sudo apt install maven
    
  2. Linux (CentOS/RHEL):
    sudo yum install maven
    
  3. macOS:
    Install Maven via Homebrew:

    brew install maven
    

Verifying Java:

Maven requires a JDK (Java Development Kit) to work. Verify that Java is installed by running:

java -version

If it’s not installed:

  • On Linux, install OpenJDK:
    sudo apt install openjdk-17-jdk   # For Ubuntu/Debian
    sudo yum install java-17-openjdk  # For CentOS/RHEL
    
  • On macOS, install OpenJDK via Homebrew:
    brew install openjdk
    

Step 4: Running Maven

You’re now ready to use Maven! Here are a few common commands:

  1. Check Maven Version:
    mvn -version
    
  2. Create a New Maven Project:
    mvn archetype:generate
    
  3. Build a Maven Project:
    mvn clean install
    

Final Thoughts

Congratulations! You’ve successfully installed and configured Apache Maven. With Maven set up on your system, you can now manage your Java projects with ease. Maven simplifies build processes, ensures consistent project management, and makes dependency management seamless. Feel free to explore its many features and extend your knowledge by diving into Maven’s powerful tools, plugins, and architecture.

Have fun coding! 🚀

How to build WAR file for Jakarta EE Servlet Container?

To build a WAR file for your Jakarta EE servlet application, the steps will vary depending on the build tool you are using. In this post I will show you how to use Apache Maven, build it in the IDE, or create it manually. Here’s how you can build a WAR file:


1. Using Maven

Maven is a widely used build tool in Java projects. If your project uses Maven, follow these steps:

a) Add WAR Packaging to pom.xml

Your pom.xml file should include these configurations:

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.kodejava</groupId>
    <artifactId>helloworld-servlet</artifactId>
    <version>1.0</version>
    <packaging>war</packaging> <!-- Specify that the packaging is WAR -->
    <name>HelloWorldServlet</name>

    <dependencies>
        <!-- Jakarta Servlet dependency -->
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.1.0</version>
            <scope>provided</scope> <!-- mark as provided since the container will provide the API -->
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- WAR Plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.4.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml> <!-- Optional for Servlet 3.0+ -->
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

b) Directory Structure for WAR Projects

Ensure your project follows the standard Maven directory structure:

src/
└── main/
    ├── java/                     --> Your Java source files
    │   └── org/kodejava/servlet/HelloWorld.java
    ├── resources/                --> (Optional) Resource files
    └── webapp/                   --> Web application files
        ├── WEB-INF/              --> Configuration files
        │   └── web.xml           --> web.xml file (if required)
        └── index.html            --> Static files (Optional)

Important Notes:

  • webapp/WEB-INF/ is the location for configuration files. For modern servlets with annotations like @WebServlet, a web.xml file may not be required.
  • Additional static resources (like HTML, CSS, or JS files) can be placed under webapp/.

c) Build the WAR File

Run the following Maven command:

mvn clean package

Once the build is successful, the WAR file will be generated in the target/ directory, named as <artifactId>-<version>.war.

For instance: target/helloworld-servlet-1.0.war


2. Using an IDE (IntelliJ IDEA, Eclipse)

Some IDEs let you build a WAR file without using Maven explicitly. For IntelliJ IDEA:

a) Configure Your Project as a WAR

  1. Open your project in IntelliJ.
  2. Go to File > Project Structure > Artifacts.
  3. Click on the + button and choose Web Application: Archive > From Modules with Dependencies.
  4. Select your module and specify the location of your web and META-INF folders.
  5. Apply and save changes.

b) Build the WAR File

  1. Go to Build > Build Artifacts > Build.
  2. The WAR file will be created in the specified output folder.

3. Manually Create a WAR

If you’re not using a build tool and want to manually create a WAR file:

a) Prepare the Required Directory Structure

Manually create a structure similar to this:

project/
└── WEB-INF/
    ├── web.xml           --> Optional (for configurations)
    └── classes/          --> Compiled `.class` files (Java code goes here)
        └── org/kodejava/servlet/HelloWorld.class

Copy all your .class files, resources, and configuration files into their respective folders.

b) Create the WAR File

Navigate to the folder containing the root project directory and run:

jar -cvf HelloWorldServlet.war *

This command will package your project into a .war file.


By following any of these methods, you’ll have a .war file ready for deployment in your Tomcat 11 server.

How do I compile and execute a JDK preview features with Maven?

To compile and execute a JDK preview features with Maven, you need to add in the following configurations in your pom.xml file:

  • Compiler Plugin: The configuration should specify the JDK version and enable the preview features. It should look similar to this:
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <release>21</release>
                <compilerArgs>--enable-preview</compilerArgs>
            </configuration>
        </plugin>
    </plugins>
</build>
  • Surefire Plugin: If you’re using the Maven Surefire Plugin to run your tests, you should also enable the preview features there. The configuration may look similar to this:
<build>
    <plugins>
    ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.2</version>
            <configuration>
                <argLine>--enable-preview</argLine>
            </configuration>
        </plugin>
    </plugins>
</build>

Before building your project, ensure that you have JDK 21-preview installed on your computer, and it’s properly set in JAVA_HOME environment variable or in the IDE settings.

Then use Maven to package or install your project:

mvn clean package
# or
mvn clean install

Please ensure that you have the correct version of maven-compiler-plugin and maven-surefire-plugin that support the JDK 21-preview features. For the project that uses Spring MVC, you should make sure all dependencies are compatible with JDK 21-preview as well.

How do I install third-party libraries in Maven repository?

Sometimes when the required libraries / dependencies is not available in the Maven Central Repository we need to manually install it to our local repository. This library must be placed in the correct directory in our local repository to enable Maven to find it. The default location is under the ${user.home}/.m2/repository.

To make this job easier Maven provides a maven-install-plugin that will help us to install the third-party library in the correct place. The following command shows how to do it.

The long command

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> \
        -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>

Where:

  • -Dfile = path to the third-party library file
  • -DgroupId = the groupId of the library
  • -DartifactId = the artifactId of the library
  • -Dversion = the version number of the library
  • -Dpackaging = the library packaging

An example to install an Oracle JDBC library to your local repository is:

mvn install:install-file -Dfile=ojdbc7.jar -DgroupId=com.oracle \
        -DartifactId=ojdbc7 -Dversion=12.1.0.2 -Dpackaging=jar

The simple command

If you have the pom.xml file, you can install it with the following command:

mvn install:install-file \
        -Dfile=<path-to-file> \
        -DpomFile=<path-to-pomfile>

Where:

  • -Dfile = path to the third-party library file
  • -DpomFile = the location to the library pom.xml file

Starting with the Maven version 2.5 you can use even a simpler command. When the library is build by Maven, a pom.xml file will be placed under the META-INF directory. This pom.xml file will be used by default when we install the library. To install a library all you need is the following command:

mvn install:install-file -Dfile=<path-to-file>

How to use Google Maven Central mirror?

The following configuration will use Google’s mirror of the Maven Central repository. Alter your ${M2_HOME}/conf/settings.xml or ${user.home}/.m2/settings.xml to add the mirror as seen in the following configuration file.

<?xml version="1.0" encoding="UTF-8"?>
<settings>
    .
    .
    <mirrors>
        <mirror>
            <id>google-maven-central</id>
            <name>Google Maven Central</name>
            <url>https://maven-central.storage.googleapis.com</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>
    .
    .
</settings>

How to configure a proxy in Maven settings?

When we work behind a proxy server, we need to configure Maven to be able to connect to the internet. To enable proxy we can configure Maven settings.xml file, either in ${M2_HOME}/conf/settings.xml or ${user.home}/.m2/settings.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<settings>
    .
    .
    <proxies>
        <proxy>
            <id>my-proxy</id>
            <active>true</active>
            <protocol>http</protocol>
            <host>proxy.example.org</host>
            <port>8080</port>
            <username>username</username>
            <password>password</password>
            <nonProxyHosts>*.example.org|*.example.com</nonProxyHosts>
        </proxy>
    </proxies>
    .
    .
</settings>

The <proxy> element in the configuration above contains the information about the proxy server. These include information about the host, port, username and password. Set these elements to match your proxy server configuration.

How do I specify the Java compiler version in a pom.xml file?

When you need to compile a project for a specific Java version you can configure maven compiler plugin to set the source and the target version. The following pom.xml file configuration show you how to do it.

<project>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>    

Invalid value for the source and the target version in our project will make our project compilation process failed. For example when we try to use the diamond operator (<>) which available in Java 7, while the maven compiler plugin is set to version 1.5, can produce compiler error like this:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project servlet-example: Compilation failure
[ERROR] /Users/wsaryada/Studio/kodejava.org/webapp-example/servlet-example/src/main/java/org/kodejava/example/servlet/SessionCounter.java:[10,51] diamond operator is not supported in -source 1.5
[ERROR] (use -source 7 or higher to enable diamond operator)

Why do I get NotOLE2FileException: Invalid header signature error?

When I was creating the code snippet for the How do I replace text in Microsoft Word document using Apache POI? I got the following error when running the snippet . As additional information, the code snippet for the Kodejava website is written as a Maven project.

org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0xE011BDBFEFBDBFEF, expected 0xE11AB1A1E011CFD0 – Your file appears not to be a valid OLE2 document

This error message was produce when the code trying to open a Word document. The Apache POI reports that the Word document has an invalid header signature, not a valid OLE2 document. Comparing the original document with the document under maven’s target directory I found out that the file size was different. This could mean that something alter the document and corrupt the header.

After doing some googling, I found out that this error is due to maven resource filtering. The maven resource filtering process cause the Word document header corrupt during the copy phase. The solution to this problem is to make sure that the filtering process is set to false. The pom.xml of the maven project should be altered to have the following configuration.

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>