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文件。
<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脚本:
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脚本的基本架构如下:
pipeline {
agent any
tools{
//工具名 '工具标识'
} // tools为可选项
stages {
stage('StageName1'){
steps {
…
}
}
stage('StageName2'){
steps {
…
}
}
…
stage('StageNamen'){
steps {
…
}
}
}
post{
//事后处理,比如展示测试报告
always{
}
}
}
4)查看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.核心功能
1)测试分类:按特性、故事、严重程度等维度组织测试
2)步骤记录:详细记录测试执行步骤
3)附件支持:可附加截图、日志、视频等
4)环境信息:记录测试执行环境
5)缺陷跟踪:与问题跟踪系统集成
3.使用流程
1)在测试框架中添加 Allure 适配器
2)执行测试并生成原始数据
3)使用 Allure 命令行工具生成 HTML 报告
4)在Jerkins中配置Allure
在Jerkins中配置Allure环境的步骤如下。
(1)安装Allure软件,将bin目录设为path
C:\Users\xiang>allure --version
2.34.1
(2)安装Jenkins Allure插件,如图所示。
安装Jenkins Allure插件
(3)选择菜单“Manage Jenkins→Global Tool Configuration”,根据所示进行配置。
(4)选择菜单“Manage Jenkins→Configure System”,按照图所示进行配置。
配置Allure Commandline
5)配置pom.xml
<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>
…
注意
<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>
以及
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit5</artifactId>
<version>2.29.1</version>
<scope>test</scope>
</dependency>
6)书写Pipeline脚本:
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.主要使用场景
o持续集成环境中的代码质量门禁
o开发过程中检查测试充分性
o识别未被测试覆盖的代码区域
o监控测试覆盖率趋势
4.报告解读
JaCoCo 生成的 HTML 报告包含:
o覆盖率概览 (所有包和类的汇总数据)
o源代码高亮显示 (绿色表示已覆盖,红色表示未覆盖)
o分支覆盖详情
o方法覆盖详情
o圈复杂度分析
5.优势
1)零侵入性:不需要修改源代码
2)高性能:对应用性能影响极小
3)丰富的报告格式:支持 HTML、XML、CSV 等多种格式
4)阈值检查:可设置覆盖率最低要求,构建失败条件
5)与构建工具深度集成:Maven、Gradle、Ant 等
JaCoCo 是 Java 生态中最流行的代码覆盖率工具之一,特别适合需要监控和提升代码质量的 Java 项目。
- JaCoCo在Jenkins中配置
1)配置pom.xml文件。
<!--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脚本:
…
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定义代码模式匹配规则(示例):
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)
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)监控
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;
- 高级使用技巧
1)增量分析(仅扫描变更代码)
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) 自定义规则开发
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)基准测试(性能优化)
text
# 使用--benchmark参数
pmd check -d src/ --benchmark -R rulesets/java/quickstart.xml
5.行业对比深度分析
6.最佳实践建议
1)渐进式引入:
o初期只启用category/java/errorprone.xml核心规则
o逐步增加design.xml等规则集
2)技术债管理:
bash
# 使用@SuppressWarnings注解临时豁免
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
public class Demo {
... }
3)团队协作方案:
o将规则配置文件ruleset.xml纳入版本控制
o使用Git pre-commit hook触发基础检查
7.前沿发展方向
oAI增强:正在试验基于机器学习的误报过滤
o多语言融合:增强对Kotlin/Swift的支持
o云原生方案:提供SaaS化分析服务(PMD Cloud)
8.官方资源矩阵
o规则库:https://docs.pmd-code.org/
o学术论文:《AST-Based Source Code Analysis with PMD》(IEEE SANER 2020)
o企业支持:提供商业版PMD Pro(含优先级支持)
PMD 特别适合追求高效代码审查和深度质量管控的技术团队,其平衡了检测深度与执行效率,是现代DevOps工具链中不可或缺的一环。建议从核心规则集入手,逐步构建定制化的代码质量防护体系。
- Jerkins下安装PMD
简单配置
1)在Jerkins下安装Violations插件。
2)配置pom.xml文件。
<!-- 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)输入命令:
mvn pmd:pmd
6)在“构建后操作”中选择“Report Violations”。
这时会出现多行数据,每行分别有四列:
第一列是“太阳”图标,是生成晴朗天气报告的此类违规次数最少的图标。例如,如果值为10,表示违规数目从0到10,生成晴天报告;11或更高则生成其他的图标。
第二列是“暴风雨”图标,是生成暴风雨天气报告的此类违规次数最少的图标。
第三列是“不稳定”图标,是导致构建不稳定类的违规数量。
第四列是XML文件名模式,这是一种Ant类型模式,用于匹配工作区中这种类型的冲突文件。多个模式之间用逗号分隔。
7)在“Source encoding”中选择“UTF-8”。
8)在PMD行中按照图所示输入,开始构建。
设置PMD
9)构建完毕,单击图标,如图所示。
PMD简单配置概要报告信息
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脚本:
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.核心功能架构
3.关键能力对比
4.技术集成方案
1)Jenkins Pipeline 集成
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示例)
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)
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)增量扫描(仅分析变更文件)
bash
sonar.scanType=incremental
2)排除测试代码
properties
sonar.exclusions=**/*Test.java,**/generated/**/*
3)分布式扫描
bash
sonar.scanner.memory=4096m # 分配更大内存
sonar.analysis.worker=4 # 多线程分析
7.与竞品技术对比
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进行设置,如图所示。
Server authentication token:选择第2)步设置的安全凭证的名称。
设置安全凭证
SonarQube servers设置
4) 由于SonarQube网络调用不支持192.168.X.X、127.0.0.1和localhost回路地址,必须先下载Linux或Windows版本的nginx。配置conf/nginx.conf
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/,如图所示。
准备在SonarQube建立网络调用
在SonarQube中创建Jenkins网络调用
6)创建pipeline 脚本:
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配置
<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代码
注意顺序
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