⚙️ How to Create a Maven Build Job with Hudson?
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.
- Click on "New Job" in the Hudson dashboard
- Enter a job name (e.g., "MyMavenProject")
- Select "Build a maven2/3 project"
- 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