⚙️ How to Create a Maven Build Job with Hudson?

• Originally published on old blog

Note: This post was originally published in 2013. Hudson has been largely superseded by Jenkins, but the principles of CI/CD and Maven integration remain fundamental. Modern CI/CD platforms include GitHub Actions, GitLab CI, and cloud-based solutions.

In this article, we will see how to create a simple Maven build job that would create a WAR file with the help of a Continuous Integration (CI) server.

Step 1: Create New Job

To build a Maven 2/3 project (Legacy), Hudson takes advantage of your POM files and drastically reduces the configuration.

  1. Click on "New Job" in the Hudson dashboard
  2. Enter a job name (e.g., "MyMavenProject")
  3. Select "Build a maven2/3 project"
  4. Click "OK"

Step 2: Configure Source Code Management

In the Source Code Management section, select your "SCM". In my case, it's "Apache Subversion". Select it and specify the "Repository URL".

Repository URL: https://svn.example.com/trunk/myproject
Credentials: username/password (if required)

If your repository has some credentials set to checkout the code, update them.

Step 3: Configure Build Settings

Under the build section, in the Root POM field, specify the pom file name.

Root POM: pom.xml
Goals and options: clean install

Step 4: Save and Build

Do you believe that we have done with the Maven build configuration setup in Hudson? The truth is, it's completed. Save the project. In the Hudson main Dashboard page, you will be able to view all the projects created.

Step 5: Execute the Build

Once everything is done, just click the "Build now" button in the left pane of the Hudson console for action.

Step 6: Monitor Build Output

Just now open up the console to check the output.

Complete Configuration Example

Here's a complete example of a Maven job configuration:

Job Name: MyMavenProject
Job Type: Build a maven2/3 project

Source Code Management:
  - Type: Subversion
  - Repository URL: https://svn.example.com/trunk/myproject
  - Credentials: username/password

Build Triggers:
  - Poll SCM: H/15 * * * * (every 15 minutes)
  - Build after other projects are built

Build:
  - Root POM: pom.xml
  - Goals and options: clean install -DskipTests
  - Use private Maven repository: true

Post-build Actions:
  - Archive the artifacts: **/*.war
  - Build other projects
  - Email notification

Advanced Maven Configuration

For more complex Maven builds, you can configure additional options:

Goals and options: 
clean install -DskipTests -Dmaven.test.skip=true -Pproduction

Maven version: Maven 3.6.3
JDK: JDK 1.8

Build Environment:
  - Add timestamps to the Console Output
  - Use secret text(s) or file(s)
  - Abort the build if it's stuck

Pre Steps:
  - Execute shell: echo "Starting build at $(date)"
  - Execute Windows batch command
  - Invoke Ant
  - Invoke Gradle script

Post Steps:
  - Execute shell: echo "Build completed at $(date)"
  - Execute Windows batch command
  - Invoke Ant
  - Invoke Gradle script

Maven Goals and Options

Common Maven goals and options for different build scenarios:

  • Clean Build: clean install
  • Skip Tests: clean install -DskipTests
  • Production Profile: clean install -Pproduction
  • Debug Mode: clean install -X
  • Offline Mode: clean install -o
  • Parallel Build: clean install -T 4

Build Triggers

Different ways to trigger Maven builds:

  • Poll SCM: Check for changes in source code repository
  • Build Periodically: Schedule builds at specific intervals
  • Build after other projects are built: Trigger after dependent projects
  • Trigger builds remotely: Allow external triggers via URL
  • GitHub hook trigger: Trigger on GitHub push events

Post-Build Actions

Actions to perform after a successful build:

  • Archive the artifacts: Store build outputs (WAR, JAR files)
  • Build other projects: Trigger downstream projects
  • Email notification: Send build results via email
  • Publish JUnit test result report: Display test results
  • Publish Cobertura Coverage Report: Show code coverage
  • Deploy to container: Deploy to Tomcat, JBoss, etc.

Maven POM Configuration

Example of a Maven POM file for web application:

<?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 
         http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.example</groupId>
    <artifactId>my-webapp</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>My Web Application</name>
    
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
            </plugin>
        </plugins>
    </build>
</project>

Build Scripts

Example shell scripts for pre and post-build actions:

Pre-Build Script

#!/bin/bash
# Pre-build script
echo "Starting Maven build at $(date)"
echo "Java version: $(java -version)"
echo "Maven version: $(mvn -version)"

# Clean workspace
rm -rf target/
rm -rf *.war

# Set environment variables
export MAVEN_OPTS="-Xmx2048m -XX:MaxPermSize=512m"

echo "Pre-build setup completed"

Post-Build Script

#!/bin/bash
# Post-build script
echo "Build completed at $(date)"

# Copy artifacts to deployment directory
if [ -f "target/*.war" ]; then
    cp target/*.war /opt/deployments/
    echo "WAR file copied to deployment directory"
fi

# Send notification
echo "Build status: $BUILD_STATUS"
if [ "$BUILD_STATUS" = "SUCCESS" ]; then
    echo "Build successful - ready for deployment"
else
    echo "Build failed - check logs for details"
fi

Modern Alternatives to Hudson

While Hudson is still functional, modern CI/CD alternatives include:

  • Jenkins: Fork of Hudson with active development
  • GitHub Actions: Native CI/CD for GitHub repositories
  • GitLab CI: Integrated CI/CD for GitLab
  • Azure DevOps: Microsoft's CI/CD platform
  • CircleCI: Cloud-based CI/CD platform
  • Travis CI: Hosted CI service
  • Bamboo: Atlassian's CI/CD tool

Best Practices

  • Use Maven Wrapper: Include Maven wrapper for consistent builds
  • Cache Dependencies: Configure Maven dependency caching
  • Parallel Execution: Use Maven parallel builds for faster execution
  • Artifact Management: Use artifact repositories (Nexus, Artifactory)
  • Build Optimization: Skip unnecessary phases and tests when appropriate
  • Monitoring: Set up build monitoring and alerting

Troubleshooting

Common issues and solutions:

  • Memory Issues: Increase MAVEN_OPTS heap size
  • Network Timeouts: Configure Maven timeout settings
  • Dependency Issues: Clear local Maven repository cache
  • Permission Issues: Ensure proper file permissions
  • JDK Version Mismatch: Verify Java version compatibility

Key Takeaways

  • Hudson/Jenkins provides powerful CI/CD capabilities for Maven projects
  • Proper Maven configuration is essential for successful builds
  • Build triggers and post-build actions automate the deployment pipeline
  • Modern CI/CD platforms offer more features and better integration
  • Best practices ensure reliable and efficient build processes