google-site-verification: google61fe8ba583a51912.html
CircleCI Orbs for Java Projects

Introduction

CircleCI Orbs are reusable packages of configuration that help automate repeated processes, speed up project setup, and enforce best practices. For Java projects, orbs can streamline CI/CD pipelines with pre-configured jobs for testing, building, and deploying Java applications.

Core Java Orbs

1. Official CircleCI Java Orb

# .circleci/config.yml version: 2.1 orbs: java: circleci/[email protected] maven: circleci/[email protected] gradle: circleci/[email protected] workflows: java-test-workflow: jobs: - java/test: version: '21' test-task: test

2. Custom Java Orb Structure

# orbs/java-orb.yml version: 2.1 description: "Custom Java CI/CD Orb" commands: setup-java: description: "Setup Java environment with caching" parameters: java-version: type: string default: "21" distribution: type: string default: "temurin" steps: - checkout - java/install-jdk: version: << parameters.java-version >> distribution: << parameters.distribution >> - restore_cache: keys: - v1-dependencies-{{ checksum "pom.xml" }}-{{ checksum "build.gradle" }} - v1-dependencies- run-tests: description: "Run tests with coverage" parameters: test-task: type: string default: "test" coverage-tool: type: string default: "jacoco" steps: - run: name: Run Tests command: | if [ -f "pom.xml" ]; then ./mvnw << parameters.test-task >> elif [ -f "build.gradle" ]; then ./gradlew << parameters.test-task >> fi - run: name: Generate Coverage Report command: | if [ "<< parameters.coverage-tool >>" == "jacoco" ]; then if [ -f "pom.xml" ]; then ./mvnw jacoco:report elif [ -f "build.gradle" ]; then ./gradlew jacocoTestReport fi fi jobs: test: docker: - image: cimg/openjdk:21.0-node resource_class: medium steps: - setup-java - run-tests - store_test_results: path: target/surefire-reports - store_artifacts: path: target/site/jacoco build: docker: - image: cimg/openjdk:21.0-node resource_class: medium steps: - setup-java - run: name: Build Artifact command: | if [ -f "pom.xml" ]; then ./mvnw clean package -DskipTests elif [ -f "build.gradle" ]; then ./gradlew clean build -x test fi - store_artifacts: path: target/*.jar destination: build-artifacts security-scan: docker: - image: cimg/openjdk:21.0-node steps: - setup-java - run: name: Dependency Vulnerability Scan command: | if [ -f "pom.xml" ]; then ./mvnw org.owasp:dependency-check-maven:check elif [ -f "build.gradle" ]; then ./gradlew dependencyCheckAnalyze fi - store_artifacts: path: target/dependency-check-report.html

Complete Java CI/CD Pipeline

1. Maven Project Configuration

# .circleci/config.yml version: 2.1 orbs: java: circleci/[email protected] maven: circleci/[email protected] sonarcloud: sonarcloud/[email protected] slack: circleci/[email protected] aws-cli: circleci/[email protected] workflows: java-maven-pipeline: jobs: - java/test: name: test-java-21 version: '21' test-task: 'test' post-steps: - store_test_results: path: target/surefire-reports - store_artifacts: path: target/site/jacoco - sonarcloud/scan: name: code-analysis context: sonarcloud requires: - test-java-21 - security-scan: name: security-scan requires: - test-java-21 - build-artifact: name: build-artifact requires: - test-java-21 - code-analysis - security-scan filters: branches: only: main - deploy-staging: name: deploy-staging requires: - build-artifact filters: branches: only: main - integration-tests: name: integration-tests requires: - deploy-staging filters: branches: only: main - deploy-production: name: deploy-production requires: - integration-tests filters: branches: only: main context: aws-production jobs: security-scan: executor: java/java21 steps: - checkout - java/install-dependencies - run: name: OWASP Dependency Check command: | ./mvnw org.owasp:dependency-check-maven:check -s settings.xml - store_artifacts: path: target/dependency-check-report.html build-artifact: executor: java/java21 steps: - checkout - java/install-dependencies - run: name: Build JAR command: ./mvnw clean package -DskipTests - persist_to_workspace: root: target paths: - *.jar deploy-staging: docker: - image: cimg/aws:2023.12 steps: - attach_workspace: at: target - aws-cli/setup: role-arn: arn:aws:iam::123456789:role/CircleCI-Staging role-session-name: circleci-staging aws-region: us-east-1 - run: name: Deploy to Staging command: | aws s3 cp target/*.jar s3://my-app-staging/artifacts/ aws ecs update-service --cluster my-app-staging --service api-service --force-new-deployment integration-tests: executor: java/java21 steps: - checkout - run: name: Run Integration Tests command: | ./mvnw verify -Pintegration-tests environment: API_BASE_URL: https://staging.myapp.com - store_test_results: path: target/failsafe-reports deploy-production: docker: - image: cimg/aws:2023.12 steps: - attach_workspace: at: target - aws-cli/setup: role-arn: arn:aws:iam::123456789:role/CircleCI-Production role-session-name: circleci-production aws-region: us-east-1 - run: name: Deploy to Production command: | aws s3 cp target/*.jar s3://my-app-production/artifacts/ aws ecs update-service --cluster my-app-production --service api-service --force-new-deployment - slack/notify: event: pass template: basic_success_1 channel: deployments

2. Gradle Project Configuration

# .circleci/config.yml version: 2.1 orbs: java: circleci/[email protected] gradle: circleci/[email protected] codecov: codecov/[email protected] workflows: java-gradle-pipeline: jobs: - test-with-gradle - code-analysis - build-and-scan - deploy jobs: test-with-gradle: executor: gradle/default steps: - checkout - gradle/load-cache - gradle/run-tests: test-command: test test-result-paths: '**/build/test-results/test/*.xml' - gradle/save-cache - store_test_results: path: build/test-results/test - store_artifacts: path: build/reports/tests/test code-analysis: executor: gradle/default steps: - checkout - gradle/load-cache - run: name: Code Quality Checks command: | ./gradlew checkstyleMain checkstyleTest pmdMain pmdTest - store_artifacts: path: build/reports/checkstyle - store_artifacts: path: build/reports/pmd build-and-scan: executor: gradle/default steps: - checkout - gradle/load-cache - run: name: Build and Security Scan command: | ./gradlew build -x test ./gradlew dependencyCheckAnalyze - store_artifacts: path: build/libs - store_artifacts: path: build/reports/dependency-check deploy: executor: gradle/default steps: - checkout - gradle/load-cache - run: name: Build Distribution command: ./gradlew assembleDist - run: name: Upload to Repository command: | ./gradlew publish

Advanced Java Orb Features

1. Multi-Module Maven Project Orb

# orbs/multi-module-java.yml version: 2.1 commands: setup-multi-module: description: "Setup for multi-module Maven projects" parameters: java-version: type: string default: "21" modules: type: string default: "*" steps: - checkout - java/install-jdk: version: << parameters.java-version >> - restore_cache: keys: - maven-multi-module-{{ checksum "pom.xml" }}-{{ checksum "**/pom.xml" }} - maven-multi-module- build-modules: description: "Build specific modules" parameters: modules: type: string default: "" profiles: type: string default: "" steps: - run: name: Build Modules command: | if [ -n "<< parameters.modules >>" ]; then MODULE_FLAG="-pl << parameters.modules >>" fi if [ -n "<< parameters.profiles >>" ]; then PROFILE_FLAG="-P << parameters.profiles >>" fi ./mvnw clean install $MODULE_FLAG $PROFILE_FLAG test-modules-parallel: description: "Run tests in parallel across modules" parameters: parallel-threads: type: integer default: 4 steps: - run: name: Parallel Tests command: | ./mvnw test -T << parameters.parallel-threads >> jobs: multi-module-test: docker: - image: cimg/openjdk:21.0 resource_class: large parallelism: 4 steps: - setup-multi-module - test-modules-parallel - store_test_results: path: */target/surefire-reports build-docker-images: docker: - image: cimg/openjdk:21.0 steps: - setup-multi-module - build-modules - run: name: Build Docker Images command: | ./mvnw spring-boot:build-image -DskipTests - run: name: Scan Docker Images command: | for module in */; do if [ -f "$module/pom.xml" ]; then IMAGE_NAME=$(basename $module) docker scan $IMAGE_NAME:latest fi done

2. Spring Boot Specific Orb

# orbs/spring-boot-orb.yml version: 2.1 commands: setup-spring-boot: description: "Setup Spring Boot specific environment" parameters: spring-boot-version: type: string default: "3.2.0" java-version: type: string default: "21" steps: - setup-java: java-version: << parameters.java-version >> - run: name: Validate Spring Boot Version command: | if [ -f "pom.xml" ]; then SPRING_VERSION=$(mvn help:evaluate -Dexpression=spring-boot.version -q -DforceStdout) echo "Using Spring Boot version: $SPRING_VERSION" fi spring-boot-test: description: "Run Spring Boot specific tests" parameters: test-profile: type: string default: "test" steps: - run: name: Run Spring Tests command: | if [ -f "pom.xml" ]; then ./mvnw test -P<< parameters.test-profile >> -Dspring.profiles.active=test else ./gradlew test -Pspring.profiles.active=test fi - run: name: Test Containers Cleanup command: | docker system prune -f build-spring-native: description: "Build Spring Native image" steps: - run: name: Build Native Image command: | if [ -f "pom.xml" ]; then ./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=myapp:native else ./gradlew bootBuildImage --imageName=myapp:native fi - store_artifacts: path: build/*.jar jobs: spring-boot-build: docker: - image: cimg/openjdk:21.0 steps: - checkout - setup-spring-boot - spring-boot-test - build-spring-native database-migration: docker: - image: cimg/openjdk:21.0 - image: cimg/postgres:15.0 environment: POSTGRES_USER: test POSTGRES_PASSWORD: test POSTGRES_DB: testdb steps: - checkout - setup-spring-boot - run: name: Run Database Migrations command: | ./mvnw flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5432/testdb environment: SPRING_PROFILES_ACTIVE: test api-docs: docker: - image: cimg/openjdk:21.0 steps: - checkout - setup-spring-boot - run: name: Generate API Documentation command: | ./mvnw spring-restdocs:asciidoc-generate - store_artifacts: path: target/generated-docs

Security and Compliance Orb

# orbs/security-compliance.yml version: 2.1 commands: license-check: description: "Check license compliance" steps: - run: name: License Compliance Check command: | if [ -f "pom.xml" ]; then ./mvnw org.codehaus.mojo:license-maven-plugin:download-licenses ./mvnw org.codehaus.mojo:license-maven-plugin:check-licenses elif [ -f "build.gradle" ]; then ./gradlew checkLicense fi sbom-generate: description: "Generate Software Bill of Materials" steps: - run: name: Generate SBOM command: | if [ -f "pom.xml" ]; then ./mvnw org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom elif [ -f "build.gradle" ]; then ./gradlew cyclonedxBom fi - store_artifacts: path: target/bom.xml security-scan: description: "Comprehensive security scanning" steps: - run: name: SAST Scan command: | if [ -f "pom.xml" ]; then ./mvnw org.sonarsource.scanner.maven:sonar-maven-plugin:sonar fi - run: name: Secret Scanning command: | git secrets --scan jobs: security-compliance: docker: - image: cimg/openjdk:21.0 steps: - checkout - setup-java - license-check - sbom-generate - security-scan

Monitoring and Notifications

1. Pipeline Notifications Orb

# orbs/notifications.yml version: 2.1 commands: notify-start: description: "Notify pipeline start" parameters: pipeline-url: type: string steps: - slack/notify: event: start template: basic_success_1 channel: builds custom: | { "attachments": [ { "title": "Build Started", "text": "Pipeline *${CIRCLE_WORKFLOW_ID}* started", "color": "#3498db" } ] } notify-success: description: "Notify pipeline success" steps: - slack/notify: event: success template: basic_success_1 channel: builds notify-failure: description: "Notify pipeline failure" steps: - slack/notify: event: fail template: basic_fail_1 channel: builds-alerts jobs: performance-metrics: docker: - image: cimg/openjdk:21.0 steps: - checkout - run: name: Collect Build Metrics command: | echo "Build time: $CIRCLE_BUILD_TIME seconds" echo "Test count: $(find . -name "TEST-*.xml" | wc -l)" when: always - store_metrics: path: metrics.xml

Best Practices Configuration

1. Java Project Template

# .circleci/config.yml version: 2.1 orbs: java-ci: your-namespace/[email protected] security: your-namespace/[email protected] notifications: your-namespace/[email protected] workflows: standard-java-pipeline: jobs: - java-ci/validate-environment - java-ci/run-unit-tests: requires: - validate-environment - security/dependency-scan: requires: - validate-environment - security/code-analysis: requires: - run-unit-tests - java-ci/build-artifact: requires: - run-unit-tests - dependency-scan - java-ci/integration-tests: requires: - build-artifact - java-ci/deploy-staging: requires: - integration-tests filters: branches: only: main - notifications/send-summary: requires: - deploy-staging filters: branches: only: main

Conclusion

CircleCI Orbs for Java projects provide powerful, reusable configuration components that can significantly streamline your CI/CD pipelines. By leveraging these orbs, teams can:

  1. Standardize builds across multiple Java projects
  2. Enforce security practices with automated scanning
  3. Accelerate setup with pre-configured jobs and commands
  4. Maintain consistency across development teams
  5. Scale efficiently as projects grow in complexity

The key to successful orb usage is starting with official orbs, creating custom orbs for organization-specific needs, and continuously refining based on team feedback and evolving requirements.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper