知乎专栏 |
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