| 知乎专栏 |
sonarqube | ERROR: [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch. sonarqube | bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] sonarqube | ERROR: Elasticsearch did not exit normally - check the logs at /opt/sonarqube/logs/sonarqube.log
/etc/sysctl.conf 增加配置项
vm.max_map_count=655360
[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.9.0.2155:sonar (default-cli) on project demo: Execution default-cli of goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.9.0.2155:sonar failed: An API incompatibility was encountered while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.9.0.2155:sonar: java.lang.UnsupportedClassVersionError: org/sonar/batch/bootstrapper/EnvironmentInformation has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
问题分析,SonarQube 系统是建立在 Java 11 的基础之上,而我们自己的代码是 Java 1.8,所以在 mvn package 的时候可以编译成功,但是在执行 mvn verify sonar:sonar 的时候 sonar-maven-plugin 需要 Java 11,所以会报错。
JDK Version Bytecode Version Java 1.0 45.0 Java 1.1 45.3 Java 1.2 46.0 Java 1.3 47.0 Java 1.4 48.0 Java 5 49.0 Java 6 50.0 Java 7 51.0 Java 8 52.0 Java 9 53.0 Java 10 54.0 Java 11 55.0 Java 12 56.0 Java 13 57.0 Java 14 58.0 Java 15 59.0 Java 16 60.0 Java 17 61.0 Java 18 62.0
更换 JDK 版本可以解决
如果你的代码无法工作在 Java 11 之上,就需要解决编译使用 Java 8,执行 sonar 时使用 Java 11,你需要安装两个JDK
[root@localhost ~]# dnf install java-11-openjdk java-11-openjdk-devel [root@localhost ~]# dnf install java-1.8.0-openjdk java-1.8.0-openjdk-devel
注意安装顺序,先安装 Java 11 再安装 Java 8,这样系统默认Java是 1.8
[root@localhost ~]# java -version openjdk version "1.8.0_312" OpenJDK Runtime Environment (build 1.8.0_312-b07) OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)
编译方法
[root@localhost ~]# java -version openjdk version "1.8.0_312" OpenJDK Runtime Environment (build 1.8.0_312-b07) OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode) [root@localhost ~]# mvn clean package [root@localhost ~]# mvn verify [root@localhost ~]# export JAVA_HOME=/usr/lib/jvm/java-11-openjdk [root@localhost ~]# PATH=$JAVA_HOME/bin:$PATH [root@localhost ~]# java -version openjdk version "11.0.13" 2021-10-19 LTS OpenJDK Runtime Environment 18.9 (build 11.0.13+8-LTS) OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8-LTS, mixed mode, sharing) [root@localhost ~]# mvn sonar:sonar -Dsonar.projectKey=api.netkiller.cn_AX0DhnglXpSwMKevAarP \ -Dsonar.host.url=http://192.168.30.12:9000 \ -Dsonar.login=161e6f54add09c966518fa45d2860bad3ebf9774
修改 Gitlab 持续集成 .gitlab-ci.yml 文件
sonarqube-check:
# image: maven:3.6.3-jdk-11
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
tags:
- shell
before_script:
- rm -rf doc sql
after_script:
- wechat -t 1 api.netkiller.cn $CI_COMMIT_BRANCH 分支代码质量和安全漏洞扫描完毕 http://192.168.30.12:9000/dashboard?id=api.netkiller.cn_AX0DhnglXpSwMKevAarP
script:
- mvn verify
- export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
- export PATH=$JAVA_HOME/bin:$PATH
- mvn sonar:sonar -Dsonar.projectKey=api.netkiller.cn_AX0DhnglXpSwMKevAarP
allow_failure: true
only:
- testing
注意:这里没有使用 docker 构建,我个人比较喜欢 Shell 执行器,它的速度比 docker 快
由于 SonarQube 使用的是 OpenJDK 11,编译代码是 1.8 会出现下面错误
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project netkiller-common: Compilation failure 582[ERROR] An unknown compilation problem occurred
配置 maven-compiler-plugin 插件,指定JDK版本
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
错误日志
[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.9.0.2155:sonar (default-cli) on project api.netkiller.cn: Project 'api.netkiller.cn_AX0DhnglXpSwMKevAarP' can't have 2 modules with the following key: api.netkiller.cn_AX0DhnglXpSwMKevAarP -> [Help 1]
出错原因,Maven 使用了 module 结构
Project |- pom.xml |- module-1 | |- pom.xml |- module-2 | |- pom.xml
父 pom.xml 中添加了
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <sonar.projectKey>api.netkiller.cn_AX0DhnglXpSwMKevAarP</sonar.projectKey> <sonar.qualitygate.wait>true</sonar.qualitygate.wait> </properties>
module-1 和 module-2 会继承 parent 中的 properties 定义。
解决方案,注释 sonar.projectKey
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <!-- <sonar.projectKey>api.netkiller.cn_AX0DhnglXpSwMKevAarP</sonar.projectKey> --> <sonar.qualitygate.wait>true</sonar.qualitygate.wait> </properties>
修改 Gitlab 持续集成 .gitlab-ci.yml 文件
mvn verify sonar:sonar -Dsonar.projectKey=api.netkiller.cn_AX0DhnglXpSwMKevAarP
stages:
- build
- test
- deploy
build-job:
stage: build
tags:
- shell
script:
- echo "Compiling the code..."
- mvn package
- echo "Compile complete."
# unit-test-job:
# stage: test
# script:
# - echo "Running unit tests... This will take about 60 seconds."
# - echo "Code coverage is 90%"
# lint-test-job:
# stage: test
# script:
# - echo "Linting code... This will take about 10 seconds."
# - echo "No lint issues found."
sonarqube-check:
image: maven:3.6.3-jdk-11
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
tags:
- docker
script:
- mvn verify sonar:sonar -Dsonar.projectKey=api.netkiller.cn_AX0DhnglXpSwMKevAarP
allow_failure: true
# only:
# - master # or the name of your main branch
deploy-job:
stage: deploy
script:
- echo "Deploying application..."
- echo "Application successfully deployed."
还有一种解决方案,我没有测试过
<sonar.projectKey>your_projectKey</sonar.projectKey>
<sonar.moduleKey>${artifactId}</sonar.moduleKey>
sonar-project.properties
# must be unique in a given SonarQube instance sonar.projectKey=ejy-finance-admin sonar.host.url=http://sonarqube.default.svc.cluster.local sonar.login=sqp_84b8d5f75bdc9dd20bf9339fb6dd5d4cda5c152d # --- optional properties --- # defaults to project key sonar.projectName=ejy-finance-admin # defaults to 'not provided' sonar.projectVersion=1.0 # Path is relative to the sonar-project.properties file. Defaults to . sonar.sources=. # Encoding of the source code. Default is default system encoding sonar.sourceEncoding=UTF-8
.gitlab-ci.yml
stages:
- build
- check
- docker
- deploy
variables:
DOCKER_REGISTRY: registry.netkiller.cn
IMAGE: $DOCKER_REGISTRY/$CI_COMMIT_BRANCH/$CI_PROJECT_NAME:$CI_COMMIT_SHORT_SHA-$CI_PIPELINE_ID
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- dist/
build-job:
stage: build
image: node:14.17-alpine
before_script:
- npm install --registry=https://registry.npm.taobao.org
script:
- npm run build:${CI_COMMIT_REF_SLUG}
after_script:
- tar zcvf $CI_PROJECT_NAME.tgz dist
- ls -l $CI_PROJECT_NAME.tgz
only:
- office
- dev
- test
tags:
- kubernetes
artifacts:
name: "$CI_PROJECT_NAME"
paths:
- $CI_PROJECT_NAME.tgz
sonarqube-check:
stage: check
image: sonarsource/sonar-scanner-cli:latest
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
GIT_DEPTH: "0"
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script:
- sonar-scanner
allow_failure: true
only:
- master
- office
tags:
- kubernetes
build-docker:
stage: docker
image: docker:latest
before_script:
- echo "$CI_REGISTRY_PASSWORD" | docker login $DOCKER_REGISTRY --username $CI_REGISTRY_USER --password-stdin
- ls -l dist
after_script:
- docker images | grep $CI_PROJECT_NAME
- docker image rm $IMAGE
script:
- docker build -t $IMAGE -f Dockerfile .
- docker push $IMAGE
only:
- office
- dev
- test
tags:
- kubernetes
deploy-job:
stage: deploy
variables:
GIT_STRATEGY: none
dependencies: []
before_script:
- kubectl -n ${CI_COMMIT_BRANCH} get pod | grep $CI_PROJECT_NAME
script:
- kubectl set image deployment/${CI_PROJECT_NAME} ${CI_PROJECT_NAME}=${IMAGE} -n ${CI_COMMIT_BRANCH}
after_script:
- kubectl -n ${CI_COMMIT_BRANCH} get pod | grep $CI_PROJECT_NAME
only:
- dev
- test
tags:
- shell
environment:
name: $CI_COMMIT_BRANCH
url: $CI_COMMIT_BRANCH.netkiller.cn/$CI_PROJECT_NAME
deploy-office:
stage: deploy
image: docker:latest
# cache: []
variables:
GIT_STRATEGY: none
PORT: 1850
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $DOCKER_REGISTRY
script:
- docker rm -f $CI_PROJECT_NAME
- docker run --restart always -d --name $CI_PROJECT_NAME -v /mnt/logs/$CI_PROJECT_NAME:/var/log/nginx -p $PORT:80 $IMAGE
after_script:
- docker ps -a | grep -w $CI_PROJECT_NAME
only:
- office
tags:
- office
environment:
name: office
url: www.netkiller.cn