当前位置: 首页 > news >正文

Sonarqube:Jenkins触发sonar扫描出现UnsupportedClassVersionError错误处理

文章目录

    • 1、问题现象
    • 2、问题根因
    • 3、解决思路
      • 3.1 解决思路1
      • 3.2 解决思路2
      • 3.3 解决思路3

1、问题现象

问题现象:在每次Jenkins触发sonar扫描时,Sonar-scanner扫描器执行都会出现UnsupportedClassVersionError异常,如下:
在这里插入图片描述

ERROR: Error during SonarQube Scanner execution
java.lang.UnsupportedClassVersionError: org/sonar/batch/bootstrapper/EnvironmentInformation has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0at java.base/java.lang.ClassLoader.defineClass1(Native Method)at java.base/java.lang.ClassLoader.defineClass(Unknown Source)at java.base/java.security.SecureClassLoader.defineClass(Unknown Source)at java.base/java.net.URLClassLoader.defineClass(Unknown Source)at java.base/java.net.URLClassLoader$1.run(Unknown Source)at java.base/java.net.URLClassLoader$1.run(Unknown Source)at java.base/java.security.AccessController.doPrivileged(Native Method)at java.base/java.net.URLClassLoader.findClass(Unknown Source)at org.sonarsource.scanner.api.internal.IsolatedClassloader.loadClass(IsolatedClassloader.java:82)at java.base/java.lang.ClassLoader.loadClass(Unknown Source)at org.sonarsource.scanner.api.internal.batch.DefaultBatchFactory.createBatch(DefaultBatchFactory.java:32)at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.base/java.lang.reflect.Method.invoke(Unknown Source)at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)at com.sun.proxy.$Proxy0.execute(Unknown Source)at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)at org.sonarsource.scanner.cli.Main.execute(Main.java:112)at org.sonarsource.scanner.cli.Main.execute(Main.java:75)at org.sonarsource.scanner.cli.Main.main(Main.java:61)
ERROR: 
ERROR: Re-run SonarQube Scanner using the -X switch to enable full debug logging.

2、问题根因

这个问题表现在于扫描环境中java版本的错误,要求执行sonar-scannerJava版本 >= Java17(class version 61),但当前环境实际Java版本为Java11(class version 55),存在不支持的类,所以报错。这个问题本身很好解决,重新配置java环境变量即可,但这里面有个坑,配置的环境变量可能会不生效,需要专门的来说一下。

根因具体有几方面

  • 1、系统默认的Java版本为Java11,导致sonar-scanner执行失败
  • 2、sonar-scanner.properties配置文件指定了Java11的版本
  • 3、sonar-scanner执行时使用了内嵌Java,并且版本为Java11(重点)

3、解决思路

3.1 解决思路1

针对第1点: 直接重新配置执行时的环境变量即可,刷新Java生效的环境。

通过在Execute shell中指定重新配置Java环境变量,添加的时候必须将PATH一起配置,否则,当PATH路径中Java11版本的配置排列在Java17之前,会被优先索引到并采用:

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=${JAVA_HOME}/bin:$PATH

在这里插入图片描述

3.2 解决思路2

针对第2点: 需要对sonar-scanner.properties中设置进行修正,将其指定为Java17的版本。

配置文件路径通常为/opt/sonarqube/sonar-scanner/conf/sonar-scanner.properties

配置内容如下:

sonar.scanner.javaHome=/usr/lib/jvm/java-17-openjdk-amd64

注意: sonar.scanner.javaHome的参数支持,需要要求sonar-scanner版本>=4.12,将sonar-scanner.properties配置完成之后,最好再根据第1点,在执行前指定Java17,sonar-scanner.properties的作用通常在执行扫描时生效。

3.3 解决思路3

针对第3点:这里面埋了个大坑,sonar-scanner脚本本身会指定Java版本,当内嵌的版本为Java11时,外部所有其他方式指定的Java配置均不生效。

检查sonar-scanner执行脚本,文件路径在这/opt/sonarqube/sonar-scanner/bin/sonar-scanner,在下面几句会指明是否使用内嵌的Java:

use_embedded_jre=true
if [ "$use_embedded_jre" = true ]; thenexport JAVA_HOME=$sonar_scanner_home/jre
fi

use_embedded_jre变量值为true时,会直接采用内嵌的java版本,将内嵌的jre路径导入export JAVA_HOME=$sonar_scanner_home/jre这一项的优先级高于其他所有的配置。当此配置为true时,我们在第1点、第2点中所修改的内容都将不生效。

解决方法: 直接修改sonar-scanner执行脚本,将use_embedded_jre设置为false,其他无需更改,即修改为如下内容:

use_embedded_jre=false
if [ "$use_embedded_jre" = true ]; thenexport JAVA_HOME=$sonar_scanner_home/jre
fi

这样就默认不会采用内嵌的Java,之后再结合第1点的配置调整环境变量。重新触发构建,可正常进行扫描:

在这里插入图片描述

如果没有Jenkins服务器权限,可以在Jenkins配置中新建Execute shell,填入以下指令,直接在命令行对sonar-scanner进行修改:除了改动use_embedded_jre值外,其他原封不动粘贴

cat << 'EOF' > /opt/sonarqube/sonar-scanner/bin/sonar-scanner
#!/bin/sh
#
# SonarQube Scanner Startup Script for Unix
#
# Optional ENV vars:
#   SONAR_SCANNER_OPTS - Parameters passed to the Java VM when running the SonarQube Scanner
#   SONAR_SCANNER_DEBUG_OPTS - Extra parameters passed to the Java VM for debugging
#   JAVA_HOME - Location of Java's installationreal_path () {target=$1(while true; docd "$(dirname "$target")"target=$(basename "$target")test -L "$target" || breaktarget=$(readlink "$target")doneecho "$(pwd -P)/$target")
}script_path=$(real_path "$0")
sonar_scanner_home=$(dirname "$script_path")/..# make it fully qualified
sonar_scanner_home=$(cd "$sonar_scanner_home" && pwd -P)jar_file=$sonar_scanner_home/lib/sonar-scanner-cli-4.2.0.1873.jar# check that sonar_scanner_home has been correctly set
if [ ! -f "$jar_file" ] ; thenecho "File does not exist: $jar_file"echo "'$sonar_scanner_home' does not point to a valid installation directory: $sonar_scanner_home"exit 1
fiuse_embedded_jre=false
if [ "$use_embedded_jre" = true ]; thenexport JAVA_HOME=$sonar_scanner_home/jre
fiif [ -n "$JAVA_HOME" ]
thenjava_cmd="$JAVA_HOME/bin/java"
elsejava_cmd="$(which java)"
fiif [ -z "$java_cmd" -o ! -x "$java_cmd" ] ; thenecho "Could not find 'java' executable in JAVA_HOME or PATH."exit 1
fiproject_home=$(pwd)#echo "Info: Using sonar-scanner at $sonar_scanner_home"
#echo "Info: Using java at $java_cmd"
#echo "Info: Using classpath $jar_file"
#echo "Info: Using project $project_home"exec "$java_cmd" \-Djava.awt.headless=true \$SONAR_SCANNER_OPTS \$SONAR_SCANNER_DEBUG_OPTS \-classpath  "$jar_file" \-Dscanner.home="$sonar_scanner_home" \-Dproject.home="$project_home" \org.sonarsource.scanner.cli.Main "$@"
EOF
http://www.lqws.cn/news/530623.html

相关文章:

  • EXILIUM×亚矩云手机:重构Web3虚拟生存法则,开启多端跨链元宇宙自由征途
  • GEO引领品牌大模型种草:迈向Web3.0与元宇宙的认知新空间
  • 【算法深练】栈特性的解题密码:LIFO规则在题型中的灵活运用
  • 供应链管理:计划相关岗位及其岗位职责
  • 【C++】ATM机模拟系统 :完整窗口实现
  • 机器学习15-规则学习-知识加强
  • MySQL-主从复制分库分表
  • WebSocket 与 HTTP 的区别及 Spring Boot 实战应用
  • 如何将视频从 iPhone 发送到 Android 设备
  • Midscene.js:使用 LLMs.txt 快速生成 AI 自动化测试用例「喂饭教程」
  • pyhton自动化采集数据脚本
  • 实现Taro小程序+nut-ui左滑删除效果
  • Go 语言中的指针
  • Java+Vue开发的SRM企业招采管理系统,一站式管理招采,助力企业高效运营
  • VC formal document and examples
  • 先考 HCIA 还是直接考 HCIP?网络工程师认证选择指南
  • 深入剖析Nginx架构及其不同使用场景下的配置
  • 蜂鸟代理IP+云手机:跨境电商多账号运营的“隐形风控引擎”
  • 手机控车一键启动汽车智能钥匙
  • Java Lambda表达式
  • CMake实践:安装与配置
  • 基于vue3+ByteMD快速搭建自己的Markdown文档编辑器
  • MySQL 中的锁机制详解:原理、实现方式与实战解析!
  • MySQL多表关系
  • Nordic 电源管理nPM1300 EK评估板介绍
  • 大模型在慢性病毒性肝炎预测及诊疗方案制定中的应用研究
  • 频宽是什么: 0.35/Tr、0.5/Tr?
  • 第七章---软件实现与编码
  • 关于 ARM64 汇编:调用流程与栈帧结构解析
  • 酒店智能门锁系统常见问题解决方法——东方仙盟