Integrating p3c-pmd with GitLab for Java Code Quality Checks

p3c-pmd Overview

p3c-pmd is a static code analysis tool that enforces Alibaba's Java coding stanndards. It extends the open-source PMD framework to specifically check for violations of the Alibaba Java Development Guidelines.

PMD Architecture

PMD operates by:

  1. Parsing source code into a Abstract Syntax Tree (AST)
  2. Appplying rule sets to traverse and analyze the AST nodes
  3. Flagging violations based on predefined patterns

p3c-pmd implements custom Java rules and XPath expressions to validate code against Alibaba's standards.

GitLab Integration Implementation

Server Hooks Configuration

GitLab provides three primary server hooks:

  1. pre-receive: Executes before accepting pushes (used for validation)
  2. update: Runs per branch being updated
  3. post-receive: Executes after successful pushes

Key environment variables available in hooks:

Variable Description
GL_ID User identifier (e.g., user-2234)
GL_REPOSITORY Project identifier (e.g., project-787)
GL_USERNAME GitLab username

Installation Steps

  1. Build p3c-pmd from source:
cd p3c-pmd
mvn clean package
  1. Configure GitLab hook:
# Project-specific
mkdir -p /path/to/repo.git/custom_hooks/pre-receive.d

# Global configuration
mkdir -p /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d

Pre-receive Hook Implementation

The hook performs:

  1. Diff analysis to identify modified Java files
  2. p3c-pmd execution against changed files
  3. Access control via whitelist/blacklist

Sample hook script:

#!/bin/bash

JAVA_HOME=/usr/local/jdk-18
PMD_JAR=/path/to/p3c-pmd.jar
RULESET=/path/to/rulesets/all-rule.xml

# Check project against blacklist
if grep -qw "${GL_REPOSITORY}" /path/to/blacklist.txt; then
  while read oldrev newrev refname; do
    changed_files=$(git diff --name-only ${oldrev} ${newrev} | grep '.java$')
    
    if [ -n "$changed_files" ]; then
      temp_dir=$(mktemp -d)
      
      for file in $changed_files; do
        mkdir -p "${temp_dir}/$(dirname ${file})"
        git show ${newrev}:${file} > "${temp_dir}/${file}"
      done
      
      java -jar $PMD_JAR -d $temp_dir -R $RULESET -f text
      result=$?
      
      if [ $result -ne 0 ]; then
        if grep -qw "${GL_USERNAME}" /path/to/whitelist.txt || \
           grep -qw "${GL_REPOSITORY}" /path/to/project-whitelist.txt; then
          result=0
        fi
      fi
      
      rm -rf $temp_dir
      exit $result
    fi
  done
fi
exit 0

Access Control Configuration

Whitelist example (user-whitelist.txt):

developer1
developer2

Project blacklist example (project-blacklist.txt):

project-123
project-456

Tags: gitlab java static-analysis code-quality p3c-pmd

Posted on Fri, 08 May 2026 10:21:22 +0000 by thines