Skip to content

Commit d01ba8c

Browse files
SONARJAVA-5691 Report dependencies
1 parent 821ddbc commit d01ba8c

File tree

9 files changed

+63
-11
lines changed

9 files changed

+63
-11
lines changed

java-frontend/src/main/java/org/sonar/java/JavaFrontend.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import java.util.HashSet;
2424
import java.util.List;
2525
import java.util.Map;
26+
import java.util.Objects;
27+
import java.util.Optional;
2628
import java.util.Set;
2729
import java.util.function.Consumer;
2830
import java.util.stream.Stream;
@@ -35,33 +37,48 @@
3537
import org.sonar.java.ast.visitors.FileLinesVisitor;
3638
import org.sonar.java.ast.visitors.SyntaxHighlighterVisitor;
3739
import org.sonar.java.caching.CacheContextImpl;
40+
import org.sonar.java.classpath.DependencyVersionInference;
3841
import org.sonar.java.collections.CollectionUtils;
3942
import org.sonar.java.exceptions.ApiMismatchException;
4043
import org.sonar.java.filters.SonarJavaIssueFilter;
4144
import org.sonar.java.model.JParserConfig;
4245
import org.sonar.java.model.VisitorsBridge;
46+
import org.sonar.java.telemetry.Telemetry;
47+
import org.sonar.java.telemetry.TelemetryKey;
4348
import org.sonar.plugins.java.api.JavaCheck;
4449
import org.sonar.plugins.java.api.JavaResourceLocator;
4550
import org.sonar.plugins.java.api.JavaVersion;
51+
import org.sonar.plugins.java.api.Version;
4652
import org.sonarsource.performance.measure.PerformanceMeasure;
4753
import org.sonarsource.performance.measure.PerformanceMeasure.Duration;
4854

55+
import static org.sonar.java.telemetry.TelemetryKey.JAVA_DEPENDENCY_LOMBOK;
56+
import static org.sonar.java.telemetry.TelemetryKey.JAVA_DEPENDENCY_SPRING_BOOT;
57+
4958
public class JavaFrontend {
5059

5160
private static final Logger LOG = LoggerFactory.getLogger(JavaFrontend.class);
5261
private static final String BATCH_ERROR_MESSAGE = "Batch Mode failed, analysis of Java Files stopped.";
5362

63+
/** List of libraries, whose presence or absence we want to report. */
64+
private static final Map<TelemetryKey, String> REPORTED_DEPENDENCIES = Map.of(
65+
JAVA_DEPENDENCY_LOMBOK, "lombok",
66+
JAVA_DEPENDENCY_SPRING_BOOT, "spring-boot"
67+
);
68+
5469
private final JavaVersion javaVersion;
5570
private final SonarComponents sonarComponents;
71+
private final Telemetry telemetry;
5672
private final List<File> globalClasspath;
5773
private final JavaAstScanner astScanner;
5874
private final JavaAstScanner astScannerForTests;
5975
private final JavaAstScanner astScannerForGeneratedFiles;
6076

61-
public JavaFrontend(JavaVersion javaVersion, SonarComponents sonarComponents, Measurer measurer,
77+
public JavaFrontend(JavaVersion javaVersion, SonarComponents sonarComponents, Measurer measurer, Telemetry telemetry,
6278
JavaResourceLocator javaResourceLocator, @Nullable SonarJavaIssueFilter postAnalysisIssueFilter, JavaCheck... visitors) {
6379
this.javaVersion = javaVersion;
6480
this.sonarComponents = sonarComponents;
81+
this.telemetry = telemetry;
6582
List<JavaCheck> commonVisitors = new ArrayList<>();
6683
commonVisitors.add(javaResourceLocator);
6784
if (postAnalysisIssueFilter != null) {
@@ -145,6 +162,15 @@ public void scan(Iterable<InputFile> sourceFiles, Iterable<InputFile> testFiles,
145162
scanAsBatch(new DefaultBatchModeContext(astScannerForTests, "Test"), testFiles);
146163
scanAsBatch(new DefaultBatchModeContext(astScannerForGeneratedFiles, "Generated"), generatedFiles);
147164
}
165+
166+
DependencyVersionInference dependencyService = new DependencyVersionInference();
167+
for (Map.Entry<TelemetryKey, String> dep : REPORTED_DEPENDENCIES.entrySet()) {
168+
dependencyService
169+
.infer(dep.getValue(), globalClasspath)
170+
.ifPresent(version ->
171+
telemetry.aggregateAsSortedSet(dep.getKey(), version.toString())
172+
);
173+
}
148174
}
149175

150176
/**

java-frontend/src/main/java/org/sonar/java/telemetry/TelemetryKey.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222
public enum TelemetryKey {
2323
JAVA_LANGUAGE_VERSION("java.language.version"),
2424
JAVA_SCANNER_APP("java.scanner_app"),
25-
JAVA_MODULE_COUNT("java.module_count");
25+
JAVA_MODULE_COUNT("java.module_count"),
26+
27+
// The last element of dependency keys should be the same as the name of its jar.
28+
JAVA_DEPENDENCY_LOMBOK("java.dependency.lombok"),
29+
JAVA_DEPENDENCY_SPRING_BOOT("java.dependency.spring-boot");
2630

2731
private final String key;
2832

java-frontend/src/test/java/org/sonar/java/JavaFrontendTest.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.sonar.java.exceptions.ApiMismatchException;
5858
import org.sonar.java.filters.SonarJavaIssueFilter;
5959
import org.sonar.java.model.JavaVersionImpl;
60+
import org.sonar.java.telemetry.NoOpTelemetry;
6061
import org.sonar.plugins.java.api.CheckRegistrar;
6162
import org.sonar.plugins.java.api.JavaCheck;
6263
import org.sonar.plugins.java.api.JavaFileScanner;
@@ -181,7 +182,7 @@ void scanning_empty_project_should_be_logged_in_file_by_file_sonarlint() {
181182

182183
@Test
183184
void scanning_empty_project_should_be_logged_in_batch() {
184-
JavaFrontend frontend = new JavaFrontend(new JavaVersionImpl(), mockSonarComponents(), new Measurer(sensorContext, mock(NoSonarFilter.class)), mock(JavaResourceLocator.class), mainCodeIssueScannerAndFilter);
185+
JavaFrontend frontend = new JavaFrontend(new JavaVersionImpl(), mockSonarComponents(), new Measurer(sensorContext, mock(NoSonarFilter.class)), new NoOpTelemetry(), mock(JavaResourceLocator.class), mainCodeIssueScannerAndFilter);
185186
frontend.scan(Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
186187

187188
assertThat(logTester.logs(Level.INFO)).containsExactly(
@@ -254,6 +255,7 @@ void test_scan_logs_when_caching_is_enabled_and_can_skip_unchanged_files() throw
254255
new JavaVersionImpl(),
255256
specificSonarComponents,
256257
mock(Measurer.class),
258+
new NoOpTelemetry(),
257259
mock(JavaResourceLocator.class),
258260
mainCodeIssueScannerAndFilter
259261
);
@@ -287,6 +289,7 @@ void test_scan_logs_when_caching_is_enabled_and_cannot_skip_unchanged_files() th
287289
new JavaVersionImpl(),
288290
specificSonarComponents,
289291
mock(Measurer.class),
292+
new NoOpTelemetry(),
290293
mock(JavaResourceLocator.class),
291294
mainCodeIssueScannerAndFilter
292295
);
@@ -320,6 +323,7 @@ void test_scan_logs_when_caching_is_enabled_and_cannot_determine_if_unchanged_fi
320323
new JavaVersionImpl(),
321324
specificSonarComponents,
322325
mock(Measurer.class),
326+
new NoOpTelemetry(),
323327
mock(JavaResourceLocator.class),
324328
mainCodeIssueScannerAndFilter
325329
);
@@ -352,6 +356,7 @@ void test_scan_logs_when_caching_is_disabled_and_can_skip_unchanged_files() thro
352356
new JavaVersionImpl(),
353357
specificSonarComponents,
354358
mock(Measurer.class),
359+
new NoOpTelemetry(),
355360
mock(JavaResourceLocator.class),
356361
mainCodeIssueScannerAndFilter
357362
);
@@ -384,6 +389,7 @@ void test_scan_logs_when_caching_is_disabled_and_cannot_skip_unchanged_files() t
384389
new JavaVersionImpl(),
385390
specificSonarComponents,
386391
mock(Measurer.class),
392+
new NoOpTelemetry(),
387393
mock(JavaResourceLocator.class),
388394
mainCodeIssueScannerAndFilter
389395
);
@@ -409,6 +415,7 @@ void test_scan_logs_when_caching_is_disabled_when_sonar_components_is_null() {
409415
new JavaVersionImpl(),
410416
mockSonarComponents(),
411417
mock(Measurer.class),
418+
new NoOpTelemetry(),
412419
mock(JavaResourceLocator.class),
413420
mainCodeIssueScannerAndFilter
414421
);
@@ -778,8 +785,13 @@ private List<InputFile> scan(MapSettings settings, SonarRuntime sonarRuntime, Li
778785
JavaVersion javaVersion = settings.asConfig().get(JavaVersion.SOURCE_VERSION)
779786
.map(JavaVersionImpl::fromString)
780787
.orElse(new JavaVersionImpl());
781-
JavaFrontend frontend = new JavaFrontend(javaVersion, sonarComponents, new Measurer(sensorContext, mock(NoSonarFilter.class)), mock(JavaResourceLocator.class),
782-
null, sonarComponents.mainChecks().toArray(new JavaCheck[0]));
788+
JavaFrontend frontend = new JavaFrontend(javaVersion,
789+
sonarComponents,
790+
new Measurer(sensorContext, mock(NoSonarFilter.class)),
791+
new NoOpTelemetry(),
792+
mock(JavaResourceLocator.class),
793+
null,
794+
sonarComponents.mainChecks().toArray(new JavaCheck[0]));
783795
frontend.scan(inputFiles, Collections.emptyList(), Collections.emptyList());
784796

785797
return inputFiles;

java-frontend/src/test/java/org/sonar/java/JavaVersionAwareVisitorTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.junit.jupiter.api.BeforeEach;
2323
import org.junit.jupiter.api.Test;
2424
import org.sonar.java.model.JavaVersionImpl;
25+
import org.sonar.java.telemetry.NoOpTelemetry;
2526
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
2627
import org.sonar.plugins.java.api.JavaCheck;
2728
import org.sonar.plugins.java.api.JavaFileScannerContext;
@@ -78,7 +79,7 @@ void no_java_version_matching() {
7879

7980
private void checkIssues(JavaVersion version) {
8081
messages.clear();
81-
JavaFrontend frontend = new JavaFrontend(version, mockSonarComponents(), mock(Measurer.class), null, null, javaChecks);
82+
JavaFrontend frontend = new JavaFrontend(version, mockSonarComponents(), mock(Measurer.class), new NoOpTelemetry(), null, null, javaChecks);
8283
frontend.scan(Collections.singletonList(TestUtils.inputFile("src/test/files/JavaVersionAwareChecks.java")),
8384
Collections.emptyList(), Collections.emptyList());
8485
}

java-frontend/src/test/java/org/sonar/java/MeasurerTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.sonar.api.issue.NoSonarFilter;
2626
import org.sonar.api.utils.PathUtils;
2727
import org.sonar.java.model.JavaVersionImpl;
28+
import org.sonar.java.telemetry.NoOpTelemetry;
2829

2930
import static org.assertj.core.api.Assertions.assertThat;
3031
import static org.mockito.Mockito.mock;
@@ -92,7 +93,7 @@ private void checkMetric(String filename, String metric, Number expectedValue) {
9293
context.fileSystem().add(inputFile);
9394

9495
Measurer measurer = new Measurer(context, mock(NoSonarFilter.class));
95-
JavaFrontend frontend = new JavaFrontend(new JavaVersionImpl(), mockSonarComponents(), measurer, null, null);
96+
JavaFrontend frontend = new JavaFrontend(new JavaVersionImpl(), mockSonarComponents(), measurer, new NoOpTelemetry(), null, null);
9697

9798
frontend.scan(Collections.singletonList(inputFile), Collections.emptyList(), Collections.emptyList());
9899

java-frontend/src/test/java/org/sonar/java/MeasurerTester.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.sonar.api.batch.sensor.measure.Measure;
3131
import org.sonar.api.issue.NoSonarFilter;
3232
import org.sonar.java.model.JavaVersionImpl;
33+
import org.sonar.java.telemetry.NoOpTelemetry;
3334
import org.sonar.plugins.java.api.JavaResourceLocator;
3435

3536
import static org.mockito.Mockito.mock;
@@ -50,7 +51,7 @@ public void setUp() {
5051
.forEach(fs::add);
5152

5253
Measurer measurer = new Measurer(context, mock(NoSonarFilter.class));
53-
JavaFrontend frontend = new JavaFrontend(new JavaVersionImpl(), mockSonarComponents(), measurer, mock(JavaResourceLocator.class), null);
54+
JavaFrontend frontend = new JavaFrontend(new JavaVersionImpl(), mockSonarComponents(), measurer, new NoOpTelemetry(), mock(JavaResourceLocator.class), null);
5455
List<InputFile> files = StreamSupport.stream(fs.inputFiles().spliterator(), false).toList();
5556
frontend.scan(files, Collections.emptyList(), Collections.emptyList());
5657
}

java-frontend/src/test/java/org/sonar/java/ast/visitors/FileLinesVisitorTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.sonar.java.SonarComponents;
3030
import org.sonar.java.TestUtils;
3131
import org.sonar.java.model.JavaVersionImpl;
32+
import org.sonar.java.telemetry.NoOpTelemetry;
3233

3334
import static org.assertj.core.api.Assertions.assertThat;
3435
import static org.mockito.Mockito.mock;
@@ -51,7 +52,7 @@ private void checkLines(String filename, FileLinesContext context) {
5152
SonarComponents sonarComponents = mock(SonarComponents.class);
5253
when(sonarComponents.fileLinesContextFor(Mockito.any(InputFile.class))).thenReturn(context);
5354

54-
JavaFrontend frontend = new JavaFrontend(new JavaVersionImpl(), mockSonarComponents(), mock(Measurer.class), null, null, new FileLinesVisitor(sonarComponents));
55+
JavaFrontend frontend = new JavaFrontend(new JavaVersionImpl(), mockSonarComponents(), mock(Measurer.class), new NoOpTelemetry(), null, null, new FileLinesVisitor(sonarComponents));
5556

5657
frontend.scan(Collections.singletonList(inputFile), Collections.emptyList(), Collections.emptyList());
5758
}

java-frontend/src/test/java/org/sonar/java/ast/visitors/SyntaxHighlighterVisitorTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.sonar.java.classpath.ClasspathForMain;
4141
import org.sonar.java.classpath.ClasspathForTest;
4242
import org.sonar.java.model.JParserConfig;
43+
import org.sonar.java.telemetry.NoOpTelemetry;
4344
import org.sonar.plugins.java.api.JavaVersion;
4445

4546
import static org.assertj.core.api.Assertions.assertThat;
@@ -255,7 +256,7 @@ void sealed_classes() {
255256

256257
private void scan(InputFile inputFile) {
257258
JavaVersion javaVersion = JParserConfig.MAXIMUM_SUPPORTED_JAVA_VERSION;
258-
JavaFrontend frontend = new JavaFrontend(javaVersion, mockSonarComponents(), mock(Measurer.class), null, null, syntaxHighlighterVisitor);
259+
JavaFrontend frontend = new JavaFrontend(javaVersion, mockSonarComponents(), mock(Measurer.class), new NoOpTelemetry(), null, null, syntaxHighlighterVisitor);
259260
frontend.scan(Collections.singletonList(inputFile), Collections.emptyList(), Collections.emptyList());
260261
}
261262

sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSensor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,12 @@ public void execute(SensorContext context) {
116116

117117
telemetry.aggregateAsSortedSet(JAVA_SCANNER_APP, settings.get("sonar.scanner.app").orElse("none"));
118118

119-
JavaFrontend frontend = new JavaFrontend(javaVersion, sonarComponents, measurer, javaResourceLocator, postAnalysisIssueFilter,
119+
JavaFrontend frontend = new JavaFrontend(javaVersion,
120+
sonarComponents,
121+
measurer,
122+
telemetry,
123+
javaResourceLocator,
124+
postAnalysisIssueFilter,
120125
sonarComponents.mainChecks().toArray(new JavaCheck[0]));
121126
frontend.scan(getSourceFiles(), getTestFiles(), runJasper(context));
122127

0 commit comments

Comments
 (0)