From 5af64e5d3a4e5188f0e5c6c7ebf8adab4d3b0cbe Mon Sep 17 00:00:00 2001 From: Pierre Date: Thu, 20 Jul 2023 11:45:02 +0200 Subject: [PATCH] SONAR-19983 warning when running scanner with a Java version older than 17 --- .../scanner/bootstrap/RuntimeJavaVersion.java | 49 ++++++++ .../bootstrap/SpringGlobalContainer.java | 8 +- .../bootstrap/RuntimeJavaVersionTest.java | 107 ++++++++++++++++++ 3 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/RuntimeJavaVersion.java create mode 100644 sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/RuntimeJavaVersionTest.java diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/RuntimeJavaVersion.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/RuntimeJavaVersion.java new file mode 100644 index 00000000000..1ef6e999c1c --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/RuntimeJavaVersion.java @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scanner.bootstrap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.notifications.AnalysisWarnings; +import org.sonar.core.documentation.DocumentationLinkGenerator; + +public class RuntimeJavaVersion { + private static final Logger LOG = LoggerFactory.getLogger(RuntimeJavaVersion.class); + public static final String LOG_MESSAGE = "SonarScanner will require Java 17 to run, starting in SonarQube 10.3"; + public static final String WARNING_MESSAGE_TEMPLATE = "SonarScanner will require Java 17 to run, starting in SonarQube 10.3. Please upgrade the" + + " version of Java that executes the scanner and refer to the documentation if needed."; + + private final DocumentationLinkGenerator documentationLinkGenerator; + private final AnalysisWarnings analysisWarnings; + + public RuntimeJavaVersion(DocumentationLinkGenerator documentationLinkGenerator, AnalysisWarnings analysisWarnings){ + this.documentationLinkGenerator = documentationLinkGenerator; + this.analysisWarnings = analysisWarnings; + } + + public void checkJavaVersion() { + Runtime.Version version = Runtime.version(); + if (version.compareTo(Runtime.Version.parse("17")) < 0) { + LOG.warn(LOG_MESSAGE); + String documentationLink = documentationLinkGenerator.getDocumentationLink("/analyzing-source-code/scanner-environment"); + analysisWarnings.addUnique(WARNING_MESSAGE_TEMPLATE.replace("{}", documentationLink)); + } + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java index b26017a0ff6..9b7bd6c4eab 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java @@ -24,6 +24,8 @@ import java.util.List; import java.util.Map; import javax.annotation.Priority; import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.Plugin; import org.sonar.api.SonarEdition; @@ -34,8 +36,6 @@ import org.sonar.api.utils.MessageException; import org.sonar.api.utils.System2; import org.sonar.api.utils.UriReader; import org.sonar.api.utils.Version; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.core.documentation.DefaultDocumentationLinkGenerator; import org.sonar.core.extension.CoreExtensionRepositoryImpl; import org.sonar.core.extension.CoreExtensionsLoader; @@ -114,7 +114,8 @@ public class SpringGlobalContainer extends SpringComponentContainer { ScannerCoreExtensionsInstaller.class, DefaultGlobalSettingsLoader.class, DefaultNewCodePeriodLoader.class, - DefaultMetricsRepositoryLoader.class); + DefaultMetricsRepositoryLoader.class, + RuntimeJavaVersion.class); } @Override @@ -134,6 +135,7 @@ public class SpringGlobalContainer extends SpringComponentContainer { if (!analysisMode.equals("publish")) { throw MessageException.of("The preview mode, along with the 'sonar.analysis.mode' parameter, is no more supported. You should stop using this parameter."); } + getComponentByType(RuntimeJavaVersion.class).checkJavaVersion(); new SpringProjectScanContainer(this).execute(); LOG.info("Analysis total time: {}", formatTime(System.currentTimeMillis() - startTime)); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/RuntimeJavaVersionTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/RuntimeJavaVersionTest.java new file mode 100644 index 00000000000..14874ae41b8 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/RuntimeJavaVersionTest.java @@ -0,0 +1,107 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scanner.bootstrap; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.slf4j.event.Level; +import org.sonar.api.notifications.AnalysisWarnings; +import org.sonar.api.testfixtures.log.LogAndArguments; +import org.sonar.api.testfixtures.log.LogTester; +import org.sonar.core.documentation.DocumentationLinkGenerator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; +import static org.sonar.scanner.bootstrap.RuntimeJavaVersion.WARNING_MESSAGE_TEMPLATE; + +public class RuntimeJavaVersionTest { + + @Rule + public LogTester logTester = new LogTester(); + + private DocumentationLinkGenerator documentLinkGenerator = mock(DocumentationLinkGenerator.class); + private AnalysisWarnings analysisWarnings = spy(AnalysisWarnings.class); + private RuntimeJavaVersion underTest = new RuntimeJavaVersion(documentLinkGenerator, analysisWarnings); + + @Before + public void before(){ + when(documentLinkGenerator.getDocumentationLink(any())).thenReturn("{}"); + } + + @Test + public void given_runtime11_should_log_message() { + try (MockedStatic utilities = Mockito.mockStatic(Runtime.class)) { + Runtime.Version version = Runtime.Version.parse("11"); + utilities.when(Runtime::version).thenReturn(version); + + underTest.checkJavaVersion(); + + assertThat(logTester.getLogs(Level.WARN)).extracting(LogAndArguments::getRawMsg) + .anyMatch(s -> s.contains(RuntimeJavaVersion.LOG_MESSAGE)); + } + } + + @Test + public void given_runtime11_should_addAnalysisWarning() { + try (MockedStatic utilities = Mockito.mockStatic(Runtime.class)) { + Runtime.Version version = Runtime.Version.parse("11"); + utilities.when(Runtime::version).thenReturn(version); + + underTest.checkJavaVersion(); + + verify(analysisWarnings).addUnique(WARNING_MESSAGE_TEMPLATE); + } + } + + + @Test + public void given_runtime17_should_notLogOrAddWarning() { + try (MockedStatic utilities = Mockito.mockStatic(Runtime.class)) { + Runtime.Version version = Runtime.Version.parse("17"); + utilities.when(Runtime::version).thenReturn(version); + + underTest.checkJavaVersion(); + + verifyNoInteractions(analysisWarnings); + assertThat(logTester.logs()).isEmpty(); + } + } + @Test + + public void given_runtime20_should_notLogOrAddWarning() { + try (MockedStatic utilities = Mockito.mockStatic(Runtime.class)) { + Runtime.Version version = Runtime.Version.parse("20"); + utilities.when(Runtime::version).thenReturn(version); + + underTest.checkJavaVersion(); + + verifyNoInteractions(analysisWarnings); + assertThat(logTester.logs()).isEmpty(); + } + } +} -- 2.39.5