What are you trying to accomplish?
Scan for normal execution
Support a new language?
No
Extend an existing one? Which one?
java
Add language-agnostic features?
No
Something else?
Add formatting code checking
What’s your specific coding challenge in developing your plugin?
I use googlejavaformat to format the code. When I deploy the plugin, I run a scan and an error occurs, prompting java.lang.NoClassDefFoundError: com/sun/source/tree/Tree
I build the jar package in jdk17.
My sonarqube is deployed using docker.
And, if relevant, please share the code that’s giving you problems:
@Rule(key = JavaCodeFormatRule.RULE_KEY, name = "code format check", description = "XXXXXXX")
public class JavaCodeFormatRule implements IRule {
private static final Logger LOGGER = Loggers.get(JavaCodeFormatRule.class);
public static final String RULE_KEY = "JavaCodeFormatRule";
@Override
public void execute(SensorContext sensorContext, InputFile file, RuleKey ruleKey) {
try {
String contents = file.contents();
Formatter formatter = new Formatter(JavaFormatterOptions.builder()
.style(JavaFormatterOptions.Style.AOSP)
.formatJavadoc(true)
.reorderModifiers(false)
.build());
String formattedCode = formatter.formatSource(contents);
if (!Objects.equals(contents, formattedCode)) {
LOGGER.error("代码未格式化!");
NewIssue newIssue = sensorContext.newIssue();
newIssue.forRule(ruleKey)
.at(newIssue.newLocation().on(file).at(file.selectLine(1)))
.save();
}
} catch (IOException | FormatterException e) {
throw new RuntimeException(e);
}
}
}
10:31:06.548 INFO Execute PMD 6.15.0 (done) | time=108493ms
10:31:06.652 INFO Sensor PmdSensor [pmd] (done) | time=108598ms
10:31:06.652 INFO Sensor JaCoCo XML Report Importer [jacoco]
10:31:06.654 INFO 'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml
10:31:06.655 INFO No report imported, no coverage information will be imported by JaCoCo XML Report Importer
10:31:06.655 INFO Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms
10:31:06.655 INFO Sensor IaC CloudFormation Sensor [iac]
10:31:06.678 INFO 0 source files to be analyzed
10:31:06.690 INFO 0/0 source files have been analyzed
10:31:06.690 INFO Sensor IaC CloudFormation Sensor [iac] (done) | time=35ms
10:31:06.690 INFO Sensor IaC Kubernetes Sensor [iac]
10:31:06.703 INFO 0 source files to be analyzed
10:31:06.704 INFO 0/0 source files have been analyzed
10:31:06.705 INFO Sensor IaC Kubernetes Sensor [iac] (done) | time=15ms
10:31:06.705 INFO Sensor JavaScript inside YAML analysis [javascript]
10:31:06.710 INFO No input files found for analysis
10:31:06.711 INFO Hit the cache for 0 out of 0
10:31:06.713 INFO Miss the cache for 0 out of 0
10:31:06.713 INFO Sensor JavaScript inside YAML analysis [javascript] (done) | time=8ms
10:31:06.713 INFO Sensor CSS Rules [javascript]
10:31:06.719 INFO No CSS, PHP, HTML or VueJS files are found in the project. CSS analysis is skipped.
10:31:06.719 INFO Sensor CSS Rules [javascript] (done) | time=6ms
10:31:06.719 INFO Sensor Analyzer all Java files [example]
10:31:07.029 INFO EXECUTION FAILURE
10:31:07.033 INFO Total time: 2:42.421s
10:31:07.034 ERROR Error during SonarScanner CLI execution
java.lang.NoClassDefFoundError: com/sun/source/tree/Tree
at org.sonarsource.plugins.custom.rules.JavaCodeFormatRule.execute(JavaCodeFormatRule.java:32)
at org.sonarsource.plugins.custom.rules.JavaFilesSensor.lambda$execute$0(JavaFilesSensor.java:58)
at java.base/java.util.HashMap$Values.forEach(Unknown Source)
at org.sonarsource.plugins.custom.rules.JavaFilesSensor.execute(JavaFilesSensor.java:58)
at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:64)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:88)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:61)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:79)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:61)
at org.sonar.scanner.scan.SpringModuleScanContainer.doAfterStart(SpringModuleScanContainer.java:82)
at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
at org.sonar.scanner.scan.SpringProjectScanContainer.scan(SpringProjectScanContainer.java:403)
at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:399)
at org.sonar.scanner.scan.SpringProjectScanContainer.doAfterStart(SpringProjectScanContainer.java:368)
at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
at org.sonar.scanner.bootstrap.SpringGlobalContainer.doAfterStart(SpringGlobalContainer.java:137)
at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:72)
at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:66)
at org.sonarsource.scanner.lib.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:41)
at java.base/jdk.internal.reflect.NativeMethod
And I also tried to add --add-opens=jdk.compiler/com.sun.source=ALL-UNNAMED to the environment variables SONAR_WEB_JAVAADDITIONALOPTS and SONAR_CE_JAVAADDITIONALOPTS of sonarqube’s docker deployment, but it still doesn’t work
And you can try passing --add-opens=jdk.compiler/com.sun.source=ALL-UNNAMED in the environment variable SONAR_SCANNER_JAVA_OPTS before running the scanner.
See documentation.
10:10:29.586 INFO Scanner configuration file: /work/sonarqub-scanner/sonar-scanner/conf/sonar-scanner.properties
10:10:29.600 INFO Project root configuration file: NONE
10:10:29.640 INFO SonarScanner CLI 6.2.1.4610
10:10:29.644 INFO Java 17.0.12 Eclipse Adoptium (64-bit)
10:10:29.645 INFO Linux 3.10.0-1160.el7.x86_64 amd64
MODULES=()
mvn clean package -Dmaven.test.skip=true -Dxjar.password=io.xjar
mvn dependency:copy-dependencies -DoutputDirectory=./tmplib
for module_dir in */; do
if [ -d "${module_dir}src/main/java" ]; then
MODULE_NAME=$(basename "$module_dir")
MODULES+=("$MODULE_NAME")
if [ ! -d "${module_dir}target" ]; then
echo "Target directory does not exist for module $MODULE_NAME"
continue
fi
echo "Current directory: $(pwd)"
echo "Looking for JAR files in: ${module_dir}target"
JAR_FILE=$(find "${module_dir}target" -maxdepth 1 -name "*.jar" | head -n 1)
if [ -z "$JAR_FILE" ]; then
echo "No JAR file found for module $MODULE_NAME"
continue
fi
for target_module_dir in */; do
if [ "$target_module_dir" != "$module_dir" ]; then
mkdir -p "${target_module_dir}tmplib"
echo "Copy ${JAR_FILE} to ${target_module_dir}tmplib/"
cp -f "$JAR_FILE" "${target_module_dir}tmplib/"
fi
done
fi
done
MODULE_PARAMS=()
for module_dir in */; do
if [ -d "$module_dir/src/main/java" ]; then
MODULE_NAME=$(basename "$module_dir")
MODULE_PARAMS+=(
# "-D${MODULE_NAME}.sonar.projectBaseDir=${module_dir}"
"-D${MODULE_NAME}.sonar.sources=src/main/java"
"-D${MODULE_NAME}.sonar.java.binaries=target/classes"
)
if [ -d "${module_dir}tmplib" ]; then
echo "Found for module ${MODULE_NAME} tmplib"
LIBRARIES=$(find "${module_dir}tmplib" -name "*.jar" | sed "s|^${module_dir}||" | tr '\n' ',')
MODULE_PARAMS+=("-D${MODULE_NAME}.sonar.java.libraries=${LIBRARIES}")
fi
fi
done
SONAR_CMD=(
"/work/sonarqub-scanner/sonar-scanner/bin/sonar-scanner"
"-Dsonar.projectKey=${SONAR_PROJECT_KEY}"
"-Dsonar.projectName=${SONAR_PROJECT_NAME}"
"-Dsonar.branch.name=${CI_COMMIT_REF_NAME}"
"-Dsonar.language=java"
"-Dsonar.java.source=1.8"
"-Dsonar.projectVersion=${SONAR_PROJECT_VERSION}"
"-Dsonar.modules=$(IFS=,; echo "${MODULES[*]}")"
"${MODULE_PARAMS[@]}"
)
"${SONAR_CMD[@]}"
Yes, the plugin is running in the scanner.
The scanner version you are using is providing a JRE from the server, which is Java 17 as you can see in the logs.
I looked at the documentation of google-java-format, and it says to add the JVM options as you suggested.