首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java、Python、C++支持Jenkins和SonarQube(二)

Java、Python、C++支持Jenkins和SonarQube(二)

作者头像
顾翔
发布2025-08-15 10:20:53
发布2025-08-15 10:20:53
25900
代码可运行
举报
运行总次数:0
代码可运行

4 Java与Jenkins和SonarQube

4.1在Jenkins基本配置

4.1.1 JDK在Jenkins配置

如图在Manage Jenkins/Tools配置

4.1.2 Maven在Jenkins配置

如图在Manage Jenkins/Tools配置

4.1.3 Jenkins Location配置

在Manage Jenkins System

4.1.4 设置字体

在Manage Jenkins System

4.2 在Jenkins中其他配置

4.2.1 JUnit5在Jenkins中的应用

在Jerkins中配置JUnit环境的步骤如下。

1)如下配置pom.xml文件。

代码语言:javascript
代码运行次数:0
运行
复制
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>    
<maven.compiler.target>17</maven.compiler.target>
<maven-compiler-plugin-version>2.3.2</maven-compiler-plugin-version>
</properties>
…
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
…
</plugin> 
</plugins>
</build>
…
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>        

2)安装Jenkins JUnit插件,如图所示。

安装Jenkins JUnit插件

3)书写Pipeline脚本:

代码语言:javascript
代码运行次数:0
运行
复制
pipeline {
    agent any
    stages {
        stage('Build'){
            steps {
                bat "mvn clean test"
            }
        }
    }
    post{
        always{
	       junit testResults:"**/target/surefire-reports/*.xml"
        }
    }
}
  • bat:执行Windows命令;如果要运行Linux命令,则使用sh。
  • junit testResults:"**/target/surefire-reports/*.xml":展示JUnit测试报告。
  • post:包含整个pipeline或阶段完成后附加的一些步骤,可选项。post可以同时包含多种条件块。下面是post的参数说明。
  • always:不论当前完成状态是什么,都执行。
  • changed:只要当前完成状态与上一次完成状态不同就执行。
  • fixed:上一次完成状态为失败或不稳定,当前完成状态为成功时执行。
  • regression:上一次完成状态为成功,当前完成状态为失败、不稳定或中止时执行。
  • aborted:当前执行结果是中止(一般是人为中止)状态时执行。
  • failure:当前完成状态为失败时执行。
  • success:当前完成状态为成功时执行。
  • unstable:当前完成状态为不稳定时执行。
  • cleanup:清理条件块。不管当前完成状态如何,在其他所有条件块被执行完成后都被执行。

Pipeline脚本的基本架构如下:

代码语言:javascript
代码运行次数:0
运行
复制
pipeline {
agent any
tools{
   //工具名 '工具标识' 
} // tools为可选项
stages {
        stage('StageName1'){
            steps {
                …
            }
        }
        stage('StageName2'){
            steps {
                …
            }
        }
        …
        stage('StageNamen'){
            steps {
                …
            }
        }
    }
    post{//事后处理,比如展示测试报告
        always{
        }
    }
} 

4)查看JUnit测试报告,如图所示。

Jenkins JUnit测试报告

4.2.2 Allure JUnit5在Jenkins中的应用

Allure 是一个轻量级、灵活且多语言的测试报告工具,用于生成美观、交互式的测试报告。它最初由 Yandex 团队开发,现在已成为开源项目。

1.主要特点

1.多语言支持:支持 Java、Python、JavaScript、Ruby、PHP、.NET 等多种编程语言

2.丰富的可视化:提供直观的图表和图形展示测试结果

3.高度可定制:可以添加步骤、附件、描述等信息增强报告

4.历史趋势:支持保存历史记录并展示测试趋势

5.集成友好:可与 Jenkins、TeamCity 等 CI 工具集成

2.核心功能

·测试分类:按特性、故事、严重程度等维度组织测试

·步骤记录:详细记录测试执行步骤

·附件支持:可附加截图、日志、视频等

·环境信息:记录测试执行环境

·缺陷跟踪:与问题跟踪系统集成

3.使用流程

1.在测试框架中添加 Allure 适配器

2.执行测试并生成原始数据

3.使用 Allure 命令行工具生成 HTML 报告

4.在Jerkins中配置Allure

在Jerkins中配置Allure环境的步骤如下。

1) 安装Allure软件,将bin目录设为path

代码语言:javascript
代码运行次数:0
运行
复制
C:\Users\xiang>allure --version
2.34.1

2)安装Jenkins Allure插件,如图所示。

安装Jenkins Allure插件

3)选择菜单“Manage Jenkins→Global Tool Configuration”,根据所示进行配置。

4)选择菜单“Manage Jenkins→Configure System”,按照图所示进行配置。

5)配置pom.xml

代码语言:javascript
代码运行次数:0
运行
复制
<build>
   <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version> <!-- 或更高稳定版本 -->
<configuration>
<argLine>${surefireArgLine}</argLine>
<testFailureIgnore>true</testFailureIgnore>
<includes>
<include>**/*Test.java</include>
<include>**/Test*.java</include>
<include>**/*Tests.java</include>
<include>**/*TestCase.java</include>
</includes>
<systemProperties>
<property>
<name>allure.results.directory</name>
<value>${project.build.directory}/allure-results</value>
</property>
<property>
<name>allure.link.issue.pattern</name>
<value>https://your-issue-tracker.com/issue/{}</value>
</property>
</systemProperties>
</configuration>
…

注意

代码语言:javascript
代码运行次数:0
运行
复制
<property>
<name>allure.results.directory</name>
<value>${project.build.directory}/allure-results</value>
</property>
<property>
<name>allure.link.issue.pattern</name>
<value>https://your-issue-tracker.com/issue/{}</value>
</property>

以及

代码语言:javascript
代码运行次数:0
运行
复制
<dependency>
        <groupId>io.qameta.allure</groupId>
        <artifactId>allure-junit5</artifactId>
        <version>2.29.1</version>
        <scope>test</scope>
</dependency> 

6)书写Pipeline脚本:

代码语言:javascript
代码运行次数:0
运行
复制
pipeline {
    agent any    
    tools{
        maven 'mvn-3.9.6'
    }
    stages{
        stage('junit'){
            steps {
                bat "mvn clean test"
            }
        }
    }
    post{
        always{
        junit testResults:"**/target/surefire-reports/*.xml"
        script{
allure([
includeProperties:false,
jdk:'',
properties:[],
reportBuildPolicy:'ALWAYS',
results:[[path:'target/surefire-reports']]
		])
	}
    }
}
} 

其中,maven 'mvn-3.9.6'为配置的Maven Name值,表示使用maven工具。script后面的代码表示测试完毕展示Allure报告。关于Allure的具体配置,可以查看网上的资料。

7)运行完毕,如图所示,单击“Allure Report”展示Allure报告。

Allure JUnit 报告

4.2.3 JaCoCo在Jenkins中的应用

JaCoCo (Java Code Coverage) 是一个开源的 Java 代码覆盖率分析工具,广泛用于测量单元测试对源代码的覆盖程度。

1.核心特性

1)多维度覆盖率分析

o行覆盖率 (Line Coverage)

o分支覆盖率 (Branch Coverage)

o方法覆盖率 (Method Coverage)

o类覆盖率 (Class Coverage)

o指令覆盖率 (Instruction Coverage)

o圈复杂度 (Cyclomatic Complexity)

2)轻量级:作为 Java 代理运行,无需对源代码进行修改

3)多种集成方式

o命令行工具

oAnt 任务

oMaven 插件

oGradle 插件

oEclipse EclEmma 插件

2.工作原理

JaCoCo 通过以下方式收集覆盖率数据:

1)插桩(Instrumentation):在字节码层面插入探针

2)执行测试:运行测试时记录执行路径

3)生成报告:分析收集的数据生成可视化报告

3.主要使用场景

·持续集成环境中的代码质量门禁

·开发过程中检查测试充分性

·识别未被测试覆盖的代码区域

·监控测试覆盖率趋势

4.报告解读

JaCoCo 生成的 HTML 报告包含:

·覆盖率概览 (所有包和类的汇总数据)

·源代码高亮显示 (绿色表示已覆盖,红色表示未覆盖)

·分支覆盖详情

·方法覆盖详情

·圈复杂度分析

5.优势

1)零侵入性:不需要修改源代码

2)高性能:对应用性能影响极小

3)丰富的报告格式:支持 HTML、XML、CSV 等多种格式

4)阈值检查:可设置覆盖率最低要求,构建失败条件

5)与构建工具深度集成:Maven、Gradle、Ant 等

JaCoCo 是 Java 生态中最流行的代码覆盖率工具之一,特别适合需要监控和提升代码质量的 Java 项目。

6. JaCoCo在Jenkins中配置

1)配置pom.xml文件。

代码语言:javascript
代码运行次数:0
运行
复制
<!--Jacoco -->
…
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.9</version>
    <executions>
        <execution>
            <id>pre-unit-test</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
            <configuration>
                <destFile>${project.build.directory}/jacoco.exec</destFile>
                <propertyName>surefireArgLine</propertyName>
                <!-- 添加以下配置 -->
                <append>true</append>
            </configuration>
        </execution>
        <execution>
            <id>post-unit-test</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

2)在Jenkins中安装JaCoCo插件,如所示。

安装JaCoCo插件

3)创建pipeline脚本:

代码语言:javascript
代码运行次数:0
运行
复制
          …
          stage('jacoco') {
            steps {
            // 只需要执行report目标,测试已在Build阶段完成
            jacoco(
                execPattern: 'target/**/*.exec',
                classPattern: 'target/classes',
                sourcePattern: 'src/main/java'
            )
            }
        }
        …
        post{
		…
		script{
publishHTML (target :[
allowMissing:false,
alwaysLinkToLastBuild:true,
keepAll:true,
reportDir:'target/site/jacoco',
reportFiles:'index.html',
reportName:'jacoco Reports',
reportTitles:'jacoco Report'])
		}

4)运行,获得测试结果,如图所示。

Jenkins JaCoCo的概要测试报告

5)单击图标,查看报告的详细信息,如图所示。

Jenkins JaCoCo测试报告详细信息

4.2.4PMD在Jerkins的应用

PMD 深入解析:静态代码分析利器

1. PMD 核心定位

PMD 是一款专注于源代码级别分析的静态检测工具,通过解析抽象语法树(AST)深度扫描代码结构,能在不运行程序的情况下发现:

·编码缺陷(如空指针风险、资源未关闭)

·风格违规(如命名不规范、冗余代码)

·设计问题(如过长方法、过度耦合)

·安全漏洞(如硬编码密码、XSS风险)

2.技术架构剖析

1)语言解析层

o支持多语言解析器:

§Java(基于JavaCC)

§Apex(Salesforce专属语言)

§JavaScript(配合Rhino引擎)

§PL/SQL(Oracle数据库脚本)

o生成AST供规则引擎分析

2)规则引擎

oXPath规则:通过XML定义代码模式匹配规则(示例):

代码语言:javascript
代码运行次数:0
运行
复制
xml
<rule name="AvoidDoubleBraceInitialization">
  <description>禁止使用双括号初始化</description>
  <priority>3</priority>
  <xpath>//AllocationExpression[ClassOrInterfaceBody]</xpath>
</rule>

oJava规则:通过继承AbstractJavaRule实现复杂检测逻辑

3)扩展机制

o支持开发自定义规则(JAR包形式加载)

o插件化架构,可扩展新语言支持

3.企业级应用方案

CI/CD 集成范例(Jenkins Pipeline)

代码语言:javascript
代码运行次数:0
运行
复制
groovy
pipeline {
  agent any
  stages {
    stage('Static Analysis') {
      steps {
        sh 'mvn pmd:pmd'  // Maven项目执行分析
        pmd canComputeNew: false, 
            pattern: '**/pmd.xml', 
            healthy: 10, 
            unHealthy: 100  // 质量门禁
      }
    }
  }
}

关键质量指标(KQI)监控

代码语言:javascript
代码运行次数:0
运行
复制
sql
-- 结合SonarQube存储分析结果
SELECT 
  project_key, 
  COUNT(*) AS violations,
  SUM(CASE WHEN severity = 'BLOCKER' THEN 1 ELSE 0 END) AS blockers
FROM pmd_issues
GROUP BY project_key
ORDER BY blockers DESC;

4. 高级使用技巧

1增量分析(仅扫描变更代码)

代码语言:javascript
代码运行次数:0
运行
复制
sql
-- 结合SonarQube存储分析结果
SELECT 
  project_key, 
  COUNT(*) AS violations,
  SUM(CASE WHEN severity = 'BLOCKER' THEN 1 ELSE 0 END) AS blockers
FROM pmd_issues
GROUP BY project_key
ORDER BY blockers DESC;

2 自定义规则开发

代码语言:javascript
代码运行次数:0
运行
复制
java
public class CustomStreamRule extends AbstractJavaRule {
  @Override
  public Object visit(ASTMethodDeclaration node, Object data) {
    if (node.getMethodName().contains("Stream")) {
      addViolation(data, node, "避免使用Stream命名方法");
    }
    return super.visit(node, data);
  }
}

3基准测试(性能优化)

代码语言:javascript
代码运行次数:0
运行
复制
text
# 使用--benchmark参数
pmd check -d src/ --benchmark -R rulesets/java/quickstart.xml

5.行业对比深度分析

维度

PMD

Checkstyle

SonarQube

检测粒度

代码逻辑层面

代码风格层面

全生命周期质量

规则定制

XPath+Java双模式

仅XML配置

需购买商业版

处理速度

单项目<10s

单项目<5s

分钟级

内存消耗

200MB左右

100MB以内

需要独立服务器

适用阶段

开发/构建阶段

代码提交阶段

持续监测阶段

6.最佳实践建议

1)渐进式引入

o初期只启用category/java/errorprone.xml核心规则

o逐步增加design.xml等规则集

2)技术债管理

代码语言:javascript
代码运行次数:0
运行
复制
bash
# 使用@SuppressWarnings注解临时豁免
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
public class Demo { ... }

3)团队协作方案

o将规则配置文件ruleset.xml纳入版本控制

o使用Git pre-commit hook触发基础检查

7.前沿发展方向

·AI增强:正在试验基于机器学习的误报过滤

·多语言融合:增强对Kotlin/Swift的支持

·云原生方案:提供SaaS化分析服务(PMD Cloud)

8.官方资源矩阵

·规则库:https://docs.pmd-code.org/

·学术论文:《AST-Based Source Code Analysis with PMD》(IEEE SANER 2020)

·企业支持:提供商业版PMD Pro(含优先级支持)

PMD 特别适合追求高效代码审查深度质量管控的技术团队,其平衡了检测深度与执行效率,是现代DevOps工具链中不可或缺的一环。建议从核心规则集入手,逐步构建定制化的代码质量防护体系。

9. Jerkins下安装PMD

简单配置

1)在Jerkins下安装Violations插件。

2)配置pom.xml文件。

代码语言:javascript
代码运行次数:0
运行
复制
   <!-- PMD 代码检查 -->  
   <plugin>  
       <groupId>org.apache.maven.plugins</groupId>  
       <artifactId>maven-pmd-plugin</artifactId>  
       <version>3.27.0</version>  
            <configuration>  
<failOnViolation>false</failOnViolation>
<printFailingErrors>true</printFailingErrors>
<rulesets>
<ruleset>/rulesets/java/quickstart.xml</ruleset>
</rulesets>
<excludes>
<exclude>**/generated/**/*.java</exclude>
<exclude>**/test/**/*.java</exclude>
</excludes>  
                <outputDirectory>${project.build.directory}/site/</outputDirectory>  
                <format>html</format>  
                <targetJdk>17</targetJdk>  
                <linkXRef>true</linkXRef>  
                <minimumTokens>100</minimumTokens> <!-- 可选:设置最小代码量阈值 -->  
                </configuration>  
    </plugin>  
    <!-- 必需:交叉引用支持 -->  
    <plugin>  
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-jxr-plugin</artifactId>  
        <version>3.3.0</version>  
    </plugin>  

JDK17 必须>3.20

3)在Jenkins中创建Freestyle project。

4)在“Build Steps”中选择“Execute Windows batch command”。

5)输入命令:

代码语言:javascript
代码运行次数:0
运行
复制
mvn pmd:pmd

6)在“构建后操作”中选择“Report Violations”。

这时会出现多行数据,每行分别有四列:

l第一列是“太阳”图标,是生成晴朗天气报告的此类违规次数最少的图标。例如,如果值为10,表示违规数目从0到10,生成晴天报告;11或更高则生成其他的图标。

l第二列是“暴风雨”图标,是生成暴风雨天气报告的此类违规次数最少的图标。

l第三列是“不稳定”图标,是导致构建不稳定类的违规数量。

l第四列是XML文件名模式,这是一种Ant类型模式,用于匹配工作区中这种类型的冲突文件。多个模式之间用逗号分隔。

7)在“Source encoding”中选择“UTF-8”。

8)在PMD行中按照图所示输入,开始构建。

设置PMD

9)构建完毕,单击图标,如图所示。

PMD简单配置概要报告信息

代码语言:javascript
代码运行次数:0
运行
复制
     stage('PMD Analysis') {
            steps {
                script {
                    // 1. 先执行PMD检查
                    bat "mvn pmd:pmd pmd:cpd"
                    // 2. 单独生成站点报告(包含HTML格式)
                    bat "mvn site:site -DgenerateReport=true"
                    // 3. 验证报告生成
                    if (!fileExists('target/site/pmd.html')) {
                        echo "警告: 未找到HTML报告,尝试备用路径..."
                        // 多模块项目可能路径不同
                        if (fileExists('target/site/pmd-pmd.html')) {
                            bat 'copy target/site/pmd-pmd.html target/site/pmd.html'
                        } else {
                            error "PMD HTML报告生成失败"
                        }
                    }
                }
            }
        }
	post{
		always{
			junit testResults:"**/target/surefire-reports/*.xml"
			script{
publishHTML (target :[
allowMissing:false,
alwaysLinkToLastBuild:true,
keepAll:true,
reportDir:'target/site',
reportFiles:'pmd.html',
reportName:'Pmd Reports',
reportTitles:'Pmd Report'])
			}

10)单击图中的某个文件,查看详细信息,如所示(PMD软件自身的缺陷,这里中文显示了乱码)。

PMD简单配置详细报告信息

图形化报告配置

1)构建pipeline脚本:

代码语言:javascript
代码运行次数:0
运行
复制
     stage('PMD Analysis') {
            steps {
                script {
                    // 1. 先执行PMD检查
                    bat "mvn pmd:pmd pmd:cpd"
                    // 2. 单独生成站点报告(包含HTML格式)
                    bat "mvn site:site -DgenerateReport=true"
                    // 3. 验证报告生成
                    if (!fileExists('target/site/pmd.html')) {
                        echo "警告: 未找到HTML报告,尝试备用路径..."
                        // 多模块项目可能路径不同
                        if (fileExists('target/site/pmd-pmd.html')) {
                            bat 'copy target/site/pmd-pmd.html target/site/pmd.html'
                        } else {
                            error "PMD HTML报告生成失败"
                        }
                    }
                }
            }
        }
	post{
		always{
			junit testResults:"**/target/surefire-reports/*.xml"
			script{
publishHTML (target :[
allowMissing:false,
alwaysLinkToLastBuild:true,
keepAll:true,
reportDir:'target/site',
reportFiles:'pmd.html',
reportName:'Pmd Reports',
reportTitles:'Pmd Report'])
			} 

2)运行,单击图标获得测试报告,如图所示。

Jenkins PMD图形化报告配置测试报告

4.2.5 SonarQube的应用

SonarQube 深度解析:企业级代码质量与安全管控平台

1.核心定位

SonarQube 是开源的代码质量持续监测平台,通过静态分析技术(SAST)实现:

·多维度质量检测:代码缺陷、安全漏洞、技术债务、测试覆盖率

·27+ 语言支持:Java/C#/Python/Go/JS/TS 等主流语言

·DevOps 集成:深度对接 CI/CD 流程,实现质量门禁(Quality Gate)

2.核心功能架构

模块

技术实现

典型应用场景

代码解析引擎

基于各语言编译器(Java→ECJ)

构建抽象语法树(AST)

规则引擎

内置 5000+ 条规则(CWE/OWASP)

检测SQL注入、XSS等漏洞

质量模型

SQALE 方法(技术债务量化)

计算修复成本(分钟/行)

分析器

SonarScanner(独立进程)

本地/CI 环境执行扫描

存储层

嵌入式H2/生产级PostgreSQL

历史趋势分析

3.关键能力对比

维度

SonarQube Community

商业版(Developer/Enterprise)

语言支持

Java/JS/Python等基础语言

支持C/C++/Kotlin/Swift等

安全检测

基础漏洞规则

含CWE Top 25/OWASP Top 10

分支分析

仅主分支

多分支/PR分析

LDAP/SSO

不支持

企业级身份集成

集群部署

单节点

横向扩展(HA模式)

4.技术集成方案

1)Jenkins Pipeline 集成

代码语言:javascript
代码运行次数:0
运行
复制
groovy
pipeline {
  agent any
  stages {
    stage('SonarQube Analysis') {
      steps {
        withSonarQubeEnv('SonarQube-Server') {
          sh 'mvn sonar:sonar -Dsonar.projectVersion=${BUILD_ID}'
        }
      }
    }
    stage("Quality Gate") {
      steps {
        timeout(time: 1, unit: 'HOURS') {
          waitForQualityGate abortPipeline: true
        }
      }
    }
  }
}

2自定义规则开发(Java示例)

代码语言:javascript
代码运行次数:0
运行
复制
java
@Rule(key = "AvoidSystemOut")
public class AvoidSystemOutRule extends IssuableSubscriptionVisitor {
  @Override
  public List<Tree.Kind> nodesToVisit() {
    return Collections.singletonList(Tree.Kind.METHOD_INVOCATION);
  }
  @Override
  public void visitNode(Tree tree) {
    MethodInvocationTree mit = (MethodInvocationTree)tree;
    if (mit.symbol().name().equals("println") && 
        mit.symbol().owner().name().equals("System.out")) {
      reportIssue(mit, "禁止使用System.out.println()");
    }
  }
}

5.企业级实践案例

某金融企业质量门禁配置(sonar-project.properties)

代码语言:javascript
代码运行次数:0
运行
复制
properties
# 关键质量阈值
sonar.qualitygate.wait=true
sonar.qualitygate.timeout=300
# 安全类指标
sonar.security.rating=1.0 (必须无高危漏洞)
sonar.security_review.rating=2.0
# 覆盖率要求
sonar.coverage.exclusions=**/test/**/*
sonar.java.coverage.minimum=80%
# 技术债务控制
sonar.debt.ratio.threshold=5%

6.性能优化技巧

1)增量扫描(仅分析变更文件)

代码语言:javascript
代码运行次数:0
运行
复制
bash
sonar.scanType=incremental

2)排除测试代码

代码语言:javascript
代码运行次数:0
运行
复制
properties
sonar.exclusions=**/*Test.java,**/generated/**/*

3)分布式扫描

代码语言:javascript
代码运行次数:0
运行
复制
bash
sonar.scanner.memory=4096m # 分配更大内存
sonar.analysis.worker=4 # 多线程分析
7.与竞品技术对比

工具

分析深度

语言覆盖

集成复杂度

适用规模

SonarQube

代码+安全+架构

27+语言

中等

中大型企业

Checkstyle

代码风格

Java为主

简单

小型项目

PMD

代码逻辑缺陷

6种语言

简单

中小团队

Fortify

安全漏洞

20+语言

复杂

金融/政府

8.演进路线

·v10.x:支持Java 17+、增强Clean Code概念

·v11.x:内置AI辅助修复建议(SonarFix)

·Cloud版:SAAS化服务(AWS/GCP集成)

9.官方资源

·社区版下载:https://www.sonarsource.com/products/sonarqube/

·规则库:https://rules.sonarsource.com/

·学术论文:《Metrics-Based Software Quality Assessment in SonarQube》(IEEE ICSME 2021)

SonarQube 特别适合需要建立标准化质量体系的研发组织,建议从社区版入手,逐步演进到商业版实现企业级管控

10. SonarQube配置

1)下载安装“SonarQube Scanner”插件。

2)通过菜单“Manage Jenkins→Manage Credentials”,选择“Stores scoped to Jenkins”下的“System”,如图所示。单击“Global credentials(unrestricted)”后,再单击图标添加凭据。

添加凭据

按照图所示的信息设置安全凭证。其中,Secret为SonarQube提供的token值。

3)通过菜单“Manage Jenkins→Configure System→SonarQube servers”对SonarQube servers进行设置,如图所示。

lhttp://192.168.0.123:9000:SonarQube的URL地址。

lServer authentication token:选择第2)步设置的安全凭证的名称。

4) 由于SonarQube网络调用不支持192.168.X.X、127.0.0.1和localhost回路地址,必须先下载Linux或Windows版本的nginx。配置conf/nginx.conf

代码语言:javascript
代码运行次数:0
运行
复制
server {
    listen 80;
    server_name sonar-webhook-proxy;
    location /sonarqube-webhook {
       proxy_pass http://localhost:8090/sonarqube-webhook;
       proxy_set_header Host $host;
}

启动nginx.exe(nginx)文件

5)在SonarQube中,通过菜单“配置→配置→网络调用”创建网络调用:http://sonar-webhook-proxy/sonarqube-webhook/,如图所示。

6)创建pipeline 脚本:

代码语言:javascript
代码运行次数:0
运行
复制
pipeline {
    agent any
    tools{
        maven 'mvn-3.8.6'
    }
    stages{
	     stage('Code Analysis'){
	 	   steps{
		      withSonarQubeEnv('SonarQube'){
				bat  '''
				mvn clean verify sonar:sonar\
				-Dsonar.projectKey=Java \
				-Dsonar.host.url=http://127.0.0.1:9000
				'''
			  }
		   }
	     }
	     stage('Quality Gate'){
	 	   steps{
			script {
				timeout(time:1,unit:'HOURS'){
		    		  sleep(5)
				  def qg = waitForQualityGate()
				  if (qg.status != 'OK'){
					echo "Status:${qg.status}"
					error "Pipeline aborted due to quality gate failure:${qg.status}"
				  }
			    }
		     }
	      }
	    }
   }
} 

注意:“withSonarQubeEnv('SonarQube'){”中的SonarQube必须与图中创建的name值保持一致。

在Jenkins中使用SonarQube进行扫描,不要使用“-Dsonar.login=admin \”和“-Dsonar.password=123456 \”。

4.3例子

PMD version: 7.14.0

allure version: 2.34.1

Jenkins:Version 2.523

SonarQube:25.8.0.112029

最后用我将要出版的《带着ChatGPT玩转软件开发》作为案例

4.3.1 pom.xml配置

代码语言:javascript
代码运行次数:0
运行
复制
<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>ebusiness</groupId>
  <artifactId>ChatGPTEbusiness</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>17</maven.compiler.source>
  	<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
  </properties>
<build>
     <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version> <!-- 或更高稳定版本 -->
<configuration>
		    <argLine>${surefireArgLine}</argLine>
		    <testFailureIgnore>true</testFailureIgnore>
<includes>
<include>**/*Test.java</include>
<include>**/Test*.java</include>
<include>**/*Tests.java</include>
<include>**/*TestCase.java</include>
</includes>
<systemProperties>
<property>
				    <name>allure.results.directory</name>
				    <value>${project.build.directory}/allure-results</value>
</property>
<property>
				    <name>allure.link.issue.pattern</name>
				    <value>https://your-issue-tracker.com/issue/{}</value>
</property>
</systemProperties>
</configuration>
</plugin>
        <!-- PMD 代码检查 -->  
        <plugin>  
            <groupId>org.apache.maven.plugins</groupId>  
            <artifactId>maven-pmd-plugin</artifactId>  
            <version>3.27.0</version>  
            <configuration>  
<failOnViolation>false</failOnViolation>
<printFailingErrors>true</printFailingErrors>
<rulesets>
<ruleset>/rulesets/java/quickstart.xml</ruleset>
</rulesets>
<excludes>
<exclude>**/generated/**/*.java</exclude>
<exclude>**/test/**/*.java</exclude>
</excludes>  
                <outputDirectory>${project.build.directory}/site/</outputDirectory>  
                <format>html</format>  
                <targetJdk>17</targetJdk>  
                <linkXRef>true</linkXRef>  
                <minimumTokens>100</minimumTokens> <!-- 可选:设置最小代码量阈值 -->  
            </configuration>  
        </plugin>  
        <!-- 必需:交叉引用支持 -->  
        <plugin>  
            <groupId>org.apache.maven.plugins</groupId>  
            <artifactId>maven-jxr-plugin</artifactId>  
            <version>3.3.0</version>  
        </plugin>   
<!--Jacoco --> 
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.9</version>
    <executions>
        <execution>
            <id>pre-unit-test</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
            <configuration>
                <destFile>${project.build.directory}/jacoco.exec</destFile>
                <propertyName>surefireArgLine</propertyName>
                <!-- 添加以下配置 -->
                <append>true</append>
            </configuration>
        </execution>
        <execution>
            <id>post-unit-test</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>
 </plugins>
</build>
<dependencies>
   <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version> <!-- 存在安全漏洞 -->
    </dependency>
<dependency>
    	<groupId>com.mysql</groupId>
    	<artifactId>mysql-connector-j</artifactId>
    	<version>8.0.33</version>
</dependency>
    <dependency>
    	<groupId>jakarta.servlet</groupId>
    	<artifactId>jakarta.servlet-api</artifactId>
    	<version>6.1.0</version>
    	<scope>provided</scope>
</dependency>
    <dependency>
    	<groupId>org.mockito</groupId> 
    	<artifactId>mockito-core</artifactId> 
    	<version>5.4.0</version>
    	<scope>test</scope> 
</dependency>
<dependency>
    	<groupId>org.mockito</groupId>
    	<artifactId>mockito-junit-jupiter</artifactId>
    	<version>5.4.0</version>
    	<scope>test</scope>
</dependency>
<dependency>
    	<groupId>org.mockito</groupId>
    	<artifactId>mockito-inline</artifactId>
    	<version>4.5.1</version>
    	<scope>test</scope>
</dependency>
<dependency>
    	<groupId>org.json</groupId>
    	<artifactId>json</artifactId>
    	<version>20210307</version>
</dependency>
<dependency>
  		<groupId>com.aliyun</groupId>
  		<artifactId>dysmsapi20170525</artifactId>
  		<version>3.1.2</version>
</dependency>
<dependency>
    	<groupId>com.aliyun</groupId>
    	<artifactId>tea</artifactId>
    	<version>1.1.14</version> 
</dependency>
<dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
        <version>4.5.16</version>
    </dependency>
<dependency>
    	<groupId>com.sun.mail</groupId>
    	<artifactId>javax.mail</artifactId>
    	<version>1.6.2</version>
</dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
    	<groupId>org.apache.commons</groupId>
    	<artifactId>commons-lang3</artifactId>
    	<version>3.12.0</version>
</dependency>
    <dependency>
    	<groupId>com.zaxxer</groupId>
    	<artifactId>HikariCP</artifactId>
    	<version>5.0.1</version>
</dependency>
<dependency>
    	<groupId>org.bouncycastle</groupId>
    	<artifactId>bcprov-jdk15on</artifactId>
    	<version>1.68</version>
</dependency>
<dependency>
    	<groupId>com.squareup.okhttp3</groupId>
    	<artifactId>okhttp</artifactId>
    	<version>4.9.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
      	<artifactId>slf4j-api</artifactId>
      	<version>2.0.7</version>
  	</dependency>
<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.25</version>
            <scope>compile</scope>
        </dependency>
  	<dependency>
    	<groupId>org.powermock</groupId>
    	<artifactId>powermock-reflect</artifactId>
    	<version>2.0.9</version>
    	<scope>test</scope>
</dependency>
<dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.9.2</version>
            <scope>test</scope>
        </dependency>
    <dependency>
        <groupId>io.qameta.allure</groupId>
        <artifactId>allure-junit5</artifactId>
        <version>2.29.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>
</project>

4.2.3 pipeline的书写

1 pipeline代码

注意顺序

代码语言:javascript
代码运行次数:0
运行
复制
pipeline {
	agent any
	tools{
		maven 'mvn-3.9.6'
	}
	stages {
          stage('Build'){
			steps {
				bat "mvn clean test"
			}
		}
          stage('Code Analysis'){
	 		steps{
                              withSonarQubeEnv('SonarQube'){
				bat  '''
				mvn clean verify sonar:sonar\
				-Dsonar.projectKey=Java \
				-Dsonar.host.url=http://127.0.0.1:9000
				'''
            			}
			}
		}
            stage('Quality Gate'){
			steps{
				script {
                                    timeout(time:5,unit:'MINUTES'){
                                    sleep(5)
						def qg = waitForQualityGate()
                                            if (qg.status != 'OK'){
                                            echo "Status:${qg.status}"
							error "Pipeline aborted due to quality gate failure:${qg.status}"
						}
					}
				}
			}
		}
              stage('jacoco') {
                steps {
                // 只需要执行report目标,测试已在Build阶段完成
                jacoco(
                  execPattern: 'target/**/*.exec',
                  classPattern: 'target/classes',
                  sourcePattern: 'src/main/java'
              )
              }
          }
          stage('PMD Analysis') {
            steps {
                script {
                    // 1. 先执行PMD检查
                    bat "mvn pmd:pmd pmd:cpd"
                    // 2. 单独生成站点报告(包含HTML格式)
                    bat "mvn site:site -DgenerateReport=true"
                    // 3. 验证报告生成
                    if (!fileExists('target/site/pmd.html')) {
                        echo "警告: 未找到HTML报告,尝试备用路径..."
                        // 多模块项目可能路径不同
                        if (fileExists('target/site/pmd-pmd.html')) {
                            bat 'copy target/site/pmd-pmd.html target/site/pmd.html'
                        } else {
                            error "PMD HTML报告生成失败"
                        }
                    }
                }
            }
        }
	}
	post{
		always{
			junit testResults:"**/target/surefire-reports/*.xml"
			script{
                        publishHTML (target :[
                        allowMissing:false,
                        alwaysLinkToLastBuild:true,
                        keepAll:true,
                        reportDir:'target/site',
                        reportFiles:'pmd.html',
                        reportName:'Pmd Reports',
                        reportTitles:'Pmd Report'])
			}
			script{
                        publishHTML (target :[
                        allowMissing:false,
                        alwaysLinkToLastBuild:true,
                        keepAll:true,
                        reportDir:'target/site/jacoco',
                        reportFiles:'index.html',
                        reportName:'jacoco Reports',
                        reportTitles:'jacoco Report'])
			}
			script{
                      allure([
                        includeProperties:false,
                        jdk:'',
                        properties:[],
                        reportBuildPolicy:'ALWAYS',
                        results:[[path:'target/surefire-reports']]
			])
		  }
	    }
	}
}

2最后结果

3单元测试结果
4 Allure Report
5 Jacoco Report
6 PMD Report
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4.1在Jenkins基本配置
    • 4.1.1 JDK在Jenkins配置
    • 4.1.2 Maven在Jenkins配置
    • 4.1.3 Jenkins Location配置
    • 4.1.4 设置字体
  • 4.2 在Jenkins中其他配置
    • 4.2.1 JUnit5在Jenkins中的应用
    • 4.2.2 Allure JUnit5在Jenkins中的应用
      • 1.主要特点
      • 2.核心功能
      • 3.使用流程
      • 4.在Jerkins中配置Allure
    • 4.2.3 JaCoCo在Jenkins中的应用
      • 1.核心特性
      • 2.工作原理
      • 3.主要使用场景
      • 4.报告解读
      • 5.优势
      • 6. JaCoCo在Jenkins中配置
    • 4.2.4PMD在Jerkins的应用
      • 1. PMD 核心定位
      • 2.技术架构剖析
      • 3.企业级应用方案
      • 6.最佳实践建议
      • 7.前沿发展方向
      • 8.官方资源矩阵
      • 9. Jerkins下安装PMD
    • 4.2.5 SonarQube的应用
      • 1.核心定位
      • 2.核心功能架构
      • 3.关键能力对比
      • 4.技术集成方案
      • 7.与竞品技术对比
      • 9.官方资源
      • 10. SonarQube配置
  • 4.3例子
    • 4.3.1 pom.xml配置
      • 1 pipeline代码
      • 3单元测试结果
      • 4 Allure Report
      • 5 Jacoco Report
      • 6 PMD Report
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档