aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2019-05-14 16:02:43 -0500
committerSonarTech <sonartech@sonarsource.com>2019-05-16 20:21:08 +0200
commit74cbdd7c043e8e9ee51d7c18aeef86db386df136 (patch)
tree480cb1cca1765b6a0d985cb754de31d325604a4e
parent9240dd9a15b317d94c1db5c94281398a16b2b36a (diff)
downloadsonarqube-74cbdd7c043e8e9ee51d7c18aeef86db386df136.tar.gz
sonarqube-74cbdd7c043e8e9ee51d7c18aeef86db386df136.zip
SONAR-12108 Support Java 11 RTE
-rw-r--r--server/sonar-main/src/main/java/org/sonar/application/command/CeJvmOptions.java12
-rw-r--r--server/sonar-main/src/main/java/org/sonar/application/command/CommandFactoryImpl.java8
-rw-r--r--server/sonar-main/src/main/java/org/sonar/application/command/JavaVersion.java33
-rw-r--r--server/sonar-main/src/main/java/org/sonar/application/command/WebJvmOptions.java16
-rw-r--r--server/sonar-main/src/test/java/org/sonar/application/command/CeJvmOptionsTest.java28
-rw-r--r--server/sonar-main/src/test/java/org/sonar/application/command/CommandFactoryImplTest.java19
-rw-r--r--server/sonar-main/src/test/java/org/sonar/application/command/WebJvmOptionsTest.java31
-rw-r--r--sonar-application/src/main/java/org/sonar/application/App.java24
-rw-r--r--sonar-duplications/src/test/java/org/sonar/duplications/java/JavaStatementBuilderTest.java58
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/System2.java19
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java13
11 files changed, 209 insertions, 52 deletions
diff --git a/server/sonar-main/src/main/java/org/sonar/application/command/CeJvmOptions.java b/server/sonar-main/src/main/java/org/sonar/application/command/CeJvmOptions.java
index 6b4502813f4..44a58d1d52d 100644
--- a/server/sonar-main/src/main/java/org/sonar/application/command/CeJvmOptions.java
+++ b/server/sonar-main/src/main/java/org/sonar/application/command/CeJvmOptions.java
@@ -24,15 +24,21 @@ import java.util.LinkedHashMap;
import java.util.Map;
public class CeJvmOptions extends JvmOptions<CeJvmOptions> {
- public CeJvmOptions(File tmpDir) {
- super(mandatoryOptions(tmpDir));
+
+ public CeJvmOptions(File tmpDir, JavaVersion javaVersion) {
+ super(mandatoryOptions(tmpDir, javaVersion));
}
- private static Map<String, String> mandatoryOptions(File tmpDir) {
+ private static Map<String, String> mandatoryOptions(File tmpDir, JavaVersion javaVersion) {
Map<String, String> res = new LinkedHashMap<>(3);
res.put("-Djava.awt.headless=", "true");
res.put("-Dfile.encoding=", "UTF-8");
res.put("-Djava.io.tmpdir=", tmpDir.getAbsolutePath());
+
+ if (javaVersion.isAtLeastJava11()) {
+ // avoid illegal reflective access operations done by MyBatis
+ res.put("--add-opens=java.base/java.util=ALL-UNNAMED", "");
+ }
return res;
}
}
diff --git a/server/sonar-main/src/main/java/org/sonar/application/command/CommandFactoryImpl.java b/server/sonar-main/src/main/java/org/sonar/application/command/CommandFactoryImpl.java
index 2afbc0310c9..738cabf841d 100644
--- a/server/sonar-main/src/main/java/org/sonar/application/command/CommandFactoryImpl.java
+++ b/server/sonar-main/src/main/java/org/sonar/application/command/CommandFactoryImpl.java
@@ -68,11 +68,13 @@ public class CommandFactoryImpl implements CommandFactory {
private final Props props;
private final File tempDir;
private final System2 system2;
+ private final JavaVersion javaVersion;
- public CommandFactoryImpl(Props props, File tempDir, System2 system2) {
+ public CommandFactoryImpl(Props props, File tempDir, System2 system2, JavaVersion javaVersion) {
this.props = props;
this.tempDir = tempDir;
this.system2 = system2;
+ this.javaVersion = javaVersion;
String javaToolOptions = system2.getenv(ENV_VAR_JAVA_TOOL_OPTIONS);
if (javaToolOptions != null && !javaToolOptions.trim().isEmpty()) {
LoggerFactory.getLogger(CommandFactoryImpl.class)
@@ -149,7 +151,7 @@ public class CommandFactoryImpl implements CommandFactory {
public JavaCommand createWebCommand(boolean leader) {
File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey());
- WebJvmOptions jvmOptions = new WebJvmOptions(tempDir)
+ WebJvmOptions jvmOptions = new WebJvmOptions(tempDir, javaVersion)
.addFromMandatoryProperty(props, WEB_JAVA_OPTS.getKey())
.addFromMandatoryProperty(props, WEB_JAVA_ADDITIONAL_OPTS.getKey());
addProxyJvmOptions(jvmOptions);
@@ -175,7 +177,7 @@ public class CommandFactoryImpl implements CommandFactory {
public JavaCommand createCeCommand() {
File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey());
- CeJvmOptions jvmOptions = new CeJvmOptions(tempDir)
+ CeJvmOptions jvmOptions = new CeJvmOptions(tempDir, javaVersion)
.addFromMandatoryProperty(props, CE_JAVA_OPTS.getKey())
.addFromMandatoryProperty(props, CE_JAVA_ADDITIONAL_OPTS.getKey());
addProxyJvmOptions(jvmOptions);
diff --git a/server/sonar-main/src/main/java/org/sonar/application/command/JavaVersion.java b/server/sonar-main/src/main/java/org/sonar/application/command/JavaVersion.java
new file mode 100644
index 00000000000..448f8d508f4
--- /dev/null
+++ b/server/sonar-main/src/main/java/org/sonar/application/command/JavaVersion.java
@@ -0,0 +1,33 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.application.command;
+
+public class JavaVersion {
+ public static final JavaVersion INSTANCE = new JavaVersion();
+
+ public boolean isAtLeastJava11() {
+ try {
+ String.class.getMethod("isBlank");
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+}
diff --git a/server/sonar-main/src/main/java/org/sonar/application/command/WebJvmOptions.java b/server/sonar-main/src/main/java/org/sonar/application/command/WebJvmOptions.java
index 998f2e25974..8e55debe854 100644
--- a/server/sonar-main/src/main/java/org/sonar/application/command/WebJvmOptions.java
+++ b/server/sonar-main/src/main/java/org/sonar/application/command/WebJvmOptions.java
@@ -24,15 +24,25 @@ import java.util.LinkedHashMap;
import java.util.Map;
public class WebJvmOptions extends JvmOptions<WebJvmOptions> {
- public WebJvmOptions(File tmpDir) {
- super(mandatoryOptions(tmpDir));
+ public WebJvmOptions(File tmpDir, JavaVersion javaVersion) {
+ super(mandatoryOptions(tmpDir, javaVersion));
}
- private static Map<String, String> mandatoryOptions(File tmpDir) {
+ private static Map<String, String> mandatoryOptions(File tmpDir, JavaVersion javaVersion) {
Map<String, String> res = new LinkedHashMap<>(3);
res.put("-Djava.awt.headless=", "true");
res.put("-Dfile.encoding=", "UTF-8");
res.put("-Djava.io.tmpdir=", tmpDir.getAbsolutePath());
+
+ if (javaVersion.isAtLeastJava11()) {
+ // avoid illegal reflective access operations done by MyBatis
+ res.put("--add-opens=java.base/java.util=ALL-UNNAMED", "");
+
+ // avoid illegal reflective access operations done by Tomcat
+ res.put("--add-opens=java.base/java.lang=ALL-UNNAMED", "");
+ res.put("--add-opens=java.base/java.io=ALL-UNNAMED", "");
+ res.put("--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED", "");
+ }
return res;
}
}
diff --git a/server/sonar-main/src/test/java/org/sonar/application/command/CeJvmOptionsTest.java b/server/sonar-main/src/test/java/org/sonar/application/command/CeJvmOptionsTest.java
index 98dcb5c9eff..863ee763340 100644
--- a/server/sonar-main/src/test/java/org/sonar/application/command/CeJvmOptionsTest.java
+++ b/server/sonar-main/src/test/java/org/sonar/application/command/CeJvmOptionsTest.java
@@ -21,22 +21,42 @@ package org.sonar.application.command;
import java.io.File;
import java.io.IOException;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class CeJvmOptionsTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
- @Test
- public void constructor_sets_mandatory_JVM_options() throws IOException {
- File tmpDir = temporaryFolder.newFolder();
- CeJvmOptions underTest = new CeJvmOptions(tmpDir);
+ private File tmpDir;
+ private JavaVersion javaVersion = mock(JavaVersion.class);
+ private CeJvmOptions underTest;
+
+ @Before
+ public void setUp() throws IOException {
+ tmpDir = temporaryFolder.newFolder();
+ }
+ @Test
+ public void constructor_sets_mandatory_JVM_options_before_java11() {
+ when(javaVersion.isAtLeastJava11()).thenReturn(false);
+ underTest = new CeJvmOptions(tmpDir, javaVersion);
assertThat(underTest.getAll()).containsExactly(
"-Djava.awt.headless=true", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=" + tmpDir.getAbsolutePath());
}
+
+ @Test
+ public void constructor_sets_mandatory_JVM_options_for_java11() {
+ when(javaVersion.isAtLeastJava11()).thenReturn(true);
+ underTest = new CeJvmOptions(tmpDir, javaVersion);
+ assertThat(underTest.getAll()).containsExactly(
+ "-Djava.awt.headless=true", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=" + tmpDir.getAbsolutePath(),
+ "--add-opens=java.base/java.util=ALL-UNNAMED");
+ }
}
diff --git a/server/sonar-main/src/test/java/org/sonar/application/command/CommandFactoryImplTest.java b/server/sonar-main/src/test/java/org/sonar/application/command/CommandFactoryImplTest.java
index 0868f4150a8..1f3a059a34c 100644
--- a/server/sonar-main/src/test/java/org/sonar/application/command/CommandFactoryImplTest.java
+++ b/server/sonar-main/src/test/java/org/sonar/application/command/CommandFactoryImplTest.java
@@ -32,15 +32,14 @@ import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
import org.sonar.application.es.EsInstallation;
+import org.sonar.application.logging.ListAppender;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.System2;
-import org.sonar.application.logging.ListAppender;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
-import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
public class CommandFactoryImplTest {
@@ -50,6 +49,8 @@ public class CommandFactoryImplTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
+ private System2 system2 = Mockito.mock(System2.class);
+ private JavaVersion javaVersion = Mockito.mock(JavaVersion.class);
private File homeDir;
private File tempDir;
private File logsDir;
@@ -71,22 +72,19 @@ public class CommandFactoryImplTest {
@Test
public void constructor_logs_no_warning_if_env_variable_JAVA_TOOL_OPTIONS_is_not_set() {
- System2 system2 = Mockito.mock(System2.class);
- when(system2.getenv(anyString())).thenReturn(null);
attachMemoryAppenderToLoggerOf(CommandFactoryImpl.class);
- new CommandFactoryImpl(new Props(new Properties()), tempDir, system2);
+ new CommandFactoryImpl(new Props(new Properties()), tempDir, system2, javaVersion);
assertThat(listAppender.getLogs()).isEmpty();
}
@Test
public void constructor_logs_warning_if_env_variable_JAVA_TOOL_OPTIONS_is_set() {
- System2 system2 = Mockito.mock(System2.class);
when(system2.getenv("JAVA_TOOL_OPTIONS")).thenReturn("sds");
attachMemoryAppenderToLoggerOf(CommandFactoryImpl.class);
- new CommandFactoryImpl(new Props(new Properties()), tempDir, system2);
+ new CommandFactoryImpl(new Props(new Properties()), tempDir, system2, javaVersion);
assertThat(listAppender.getLogs())
.extracting(ILoggingEvent::getMessage)
@@ -97,11 +95,10 @@ public class CommandFactoryImplTest {
@Test
public void constructor_logs_warning_if_env_variable_ES_JAVA_OPTS_is_set() {
- System2 system2 = Mockito.mock(System2.class);
when(system2.getenv("ES_JAVA_OPTS")).thenReturn("xyz");
attachMemoryAppenderToLoggerOf(CommandFactoryImpl.class);
- new CommandFactoryImpl(new Props(new Properties()), tempDir, system2);
+ new CommandFactoryImpl(new Props(new Properties()), tempDir, system2, javaVersion);
assertThat(listAppender.getLogs())
.extracting(ILoggingEvent::getMessage)
@@ -120,7 +117,6 @@ public class CommandFactoryImplTest {
@Test
public void createEsCommand_for_unix_returns_command_for_default_settings() throws Exception {
- System2 system2 = Mockito.mock(System2.class);
when(system2.isOsWindows()).thenReturn(false);
prepareEsFileSystem();
@@ -157,7 +153,6 @@ public class CommandFactoryImplTest {
@Test
public void createEsCommand_for_windows_returns_command_for_default_settings() throws Exception {
- System2 system2 = Mockito.mock(System2.class);
when(system2.isOsWindows()).thenReturn(true);
prepareEsFileSystem();
@@ -326,7 +321,7 @@ public class CommandFactoryImplTest {
Props props = new Props(p);
ProcessProperties.completeDefaults(props);
- return new CommandFactoryImpl(props, tempDir, system2);
+ return new CommandFactoryImpl(props, tempDir, system2, javaVersion);
}
private <T> void attachMemoryAppenderToLoggerOf(Class<T> loggerClass) {
diff --git a/server/sonar-main/src/test/java/org/sonar/application/command/WebJvmOptionsTest.java b/server/sonar-main/src/test/java/org/sonar/application/command/WebJvmOptionsTest.java
index 0f0b42e72f3..8cc87861f5f 100644
--- a/server/sonar-main/src/test/java/org/sonar/application/command/WebJvmOptionsTest.java
+++ b/server/sonar-main/src/test/java/org/sonar/application/command/WebJvmOptionsTest.java
@@ -21,23 +21,46 @@ package org.sonar.application.command;
import java.io.File;
import java.io.IOException;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class WebJvmOptionsTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
- @Test
- public void constructor_sets_mandatory_JVM_options() throws IOException {
- File tmpDir = temporaryFolder.newFolder();
- WebJvmOptions underTest = new WebJvmOptions(tmpDir);
+ private File tmpDir;
+ private JavaVersion javaVersion = mock(JavaVersion.class);
+ private WebJvmOptions underTest;
+
+ @Before
+ public void setUp() throws IOException {
+ tmpDir = temporaryFolder.newFolder();
+ }
+ @Test
+ public void constructor_sets_mandatory_JVM_options_before_java11() {
+ when(javaVersion.isAtLeastJava11()).thenReturn(false);
+ underTest = new WebJvmOptions(tmpDir, javaVersion);
assertThat(underTest.getAll()).containsExactly(
"-Djava.awt.headless=true", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=" + tmpDir.getAbsolutePath());
}
+ @Test
+ public void constructor_sets_mandatory_JVM_options_for_java11() {
+ when(javaVersion.isAtLeastJava11()).thenReturn(true);
+ underTest = new WebJvmOptions(tmpDir, javaVersion);
+ assertThat(underTest.getAll()).containsExactly(
+ "-Djava.awt.headless=true", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=" + tmpDir.getAbsolutePath(),
+ "--add-opens=java.base/java.util=ALL-UNNAMED",
+ "--add-opens=java.base/java.lang=ALL-UNNAMED",
+ "--add-opens=java.base/java.io=ALL-UNNAMED",
+ "--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED");
+ }
+
}
diff --git a/sonar-application/src/main/java/org/sonar/application/App.java b/sonar-application/src/main/java/org/sonar/application/App.java
index 268d4c997e8..d262fe5df9c 100644
--- a/sonar-application/src/main/java/org/sonar/application/App.java
+++ b/sonar-application/src/main/java/org/sonar/application/App.java
@@ -20,8 +20,12 @@
package org.sonar.application;
import java.io.IOException;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.SonarEdition;
+import org.sonar.api.internal.MetadataLoader;
import org.sonar.application.command.CommandFactory;
import org.sonar.application.command.CommandFactoryImpl;
+import org.sonar.application.command.JavaVersion;
import org.sonar.application.config.AppSettings;
import org.sonar.application.config.AppSettingsLoader;
import org.sonar.application.config.AppSettingsLoaderImpl;
@@ -38,8 +42,13 @@ import static org.sonar.process.ProcessProperties.Property.CLUSTER_NAME;
public class App {
private final SystemExit systemExit = new SystemExit();
+ private final JavaVersion javaVersion;
private StopRequestWatcher stopRequestWatcher;
+ public App(JavaVersion javaVersion) {
+ this.javaVersion = javaVersion;
+ }
+
public void start(String[] cliArguments) throws IOException {
AppSettingsLoader settingsLoader = new AppSettingsLoaderImpl(cliArguments);
AppSettings settings = settingsLoader.load();
@@ -47,13 +56,14 @@ public class App {
AppLogging logging = new AppLogging(settings);
logging.configure();
AppFileSystem fileSystem = new AppFileSystem(settings);
+ checkJavaVersion();
try (AppState appState = new AppStateFactory(settings).create()) {
appState.registerSonarQubeVersion(getSonarqubeVersion());
appState.registerClusterName(settings.getProps().nonNullValue(CLUSTER_NAME.getKey()));
AppReloader appReloader = new AppReloaderImpl(settingsLoader, fileSystem, appState, logging);
fileSystem.reset();
- CommandFactory commandFactory = new CommandFactoryImpl(settings.getProps(), fileSystem.getTempDir(), System2.INSTANCE);
+ CommandFactory commandFactory = new CommandFactoryImpl(settings.getProps(), fileSystem.getTempDir(), System2.INSTANCE, JavaVersion.INSTANCE);
try (ProcessLauncher processLauncher = new ProcessLauncherImpl(fileSystem.getTempDir())) {
Scheduler scheduler = new SchedulerImpl(settings, appReloader, commandFactory, processLauncher, appState);
@@ -74,8 +84,18 @@ public class App {
systemExit.exit(0);
}
+ private void checkJavaVersion() {
+ if (MetadataLoader.loadEdition(org.sonar.api.utils.System2.INSTANCE) == SonarEdition.SONARCLOUD) {
+ return;
+ }
+
+ if (!javaVersion.isAtLeastJava11()) {
+ LoggerFactory.getLogger(this.getClass()).warn("SonarQube will require Java 11+ starting on next version");
+ }
+ }
+
public static void main(String... args) throws IOException {
- new App().start(args);
+ new App(JavaVersion.INSTANCE).start(args);
}
private class ShutdownHook extends Thread {
diff --git a/sonar-duplications/src/test/java/org/sonar/duplications/java/JavaStatementBuilderTest.java b/sonar-duplications/src/test/java/org/sonar/duplications/java/JavaStatementBuilderTest.java
index c739fa666ab..92b2085ef3d 100644
--- a/sonar-duplications/src/test/java/org/sonar/duplications/java/JavaStatementBuilderTest.java
+++ b/sonar-duplications/src/test/java/org/sonar/duplications/java/JavaStatementBuilderTest.java
@@ -19,13 +19,6 @@
*/
package org.sonar.duplications.java;
-import org.apache.commons.io.IOUtils;
-import org.junit.Test;
-import org.sonar.duplications.DuplicationsTestUtil;
-import org.sonar.duplications.statement.Statement;
-import org.sonar.duplications.statement.StatementChunker;
-import org.sonar.duplications.token.TokenChunker;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -33,6 +26,12 @@ import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.List;
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.sonar.duplications.DuplicationsTestUtil;
+import org.sonar.duplications.statement.Statement;
+import org.sonar.duplications.statement.StatementChunker;
+import org.sonar.duplications.token.TokenChunker;
import static org.assertj.core.api.Assertions.assertThat;
@@ -318,6 +317,51 @@ public class JavaStatementBuilderTest {
assertThat(statements.get(1).getValue()).isEqualTo("something()");
}
+ /**
+ * Java 8.
+ */
+ @Test
+ public void shouldHandleLambda() {
+ List<Statement> statements;
+ statements = chunk("List<String> result = lines.stream().filter(line -> !\"mkyong\".equals(line)).collect(Collectors.toList());");
+ assertThat(statements.size()).isEqualTo(1);
+ assertThat(statements).extracting(Statement::getValue).containsExactly("List<String>result=lines.stream().filter(line->!$CHARS.equals(line)).collect(Collectors.toList())");
+
+ statements = chunk("items.forEach((k,v)->{System.out.println(\"Item : \" + k + \" Count : \" + v); if(\"E\".equals(k)) { System.out.println(\"Hello E\");}});");
+ assertThat(statements.size()).isEqualTo(5);
+ assertThat(statements).extracting(Statement::getValue)
+ .containsExactly("items.forEach((k,v)->",
+ "System.out.println($CHARS+k+$CHARS+v)",
+ "if($CHARS.equals(k))",
+ "System.out.println($CHARS)",
+ ")");
+ }
+
+ /**
+ * Java 9.
+ */
+ @Test
+ public void shouldHandleModuleInfo() {
+ List<Statement> statements;
+ statements = chunk("module com.application.infra { requires com.application.domain; exports com.application.infra.api; }");
+ assertThat(statements.size()).isEqualTo(3);
+ assertThat(statements).extracting(Statement::getValue)
+ .containsExactly("modulecom.application.infra",
+ "requirescom.application.domain",
+ "exportscom.application.infra.api");
+ }
+
+ /**
+ * Java 11.
+ */
+ @Test
+ public void shouldHandleVar() {
+ List<Statement> statements;
+ statements = chunk("IFunc f = (@NonNull var x, final var y) -> Foo.foo(x, y);");
+ assertThat(statements.size()).isEqualTo(1);
+ assertThat(statements).extracting(Statement::getValue).containsExactly("IFuncf=(@NonNullvarx,finalvary)->Foo.foo(x,y)");
+ }
+
@Test
public void realExamples() {
assertThat(chunk(DuplicationsTestUtil.findFile("/java/MessageResources.java")).size()).isGreaterThan(0);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/System2.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/System2.java
index 2f2ee31eef1..36dc553a74e 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/System2.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/System2.java
@@ -21,14 +21,13 @@ package org.sonar.api.utils;
import java.net.URL;
import java.time.Clock;
-import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.TimeZone;
import javax.annotation.CheckForNull;
import org.apache.commons.lang.SystemUtils;
-import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.server.ServerSide;
/**
@@ -61,7 +60,6 @@ import org.sonar.api.server.ServerSide;
* Note that the name System2 was chosen to not conflict with {@link java.lang.System}.
* <br>
* An instance is available in IoC container since 4.3.
- *
* Since 6.4 you can also inject {@link Clock} instead of {@link System2} if you are only interested by date/time operations
*
* @since 4.2
@@ -98,6 +96,7 @@ public class System2 {
/**
* Shortcut for {@code System{@link #setProperty(String, String)}}
+ *
* @since 6.4
*/
public System2 setProperty(String key, String value) {
@@ -129,6 +128,7 @@ public class System2 {
/**
* True if Java 7 or Java 8 runtime environment
+ *
* @since 4.3
* @deprecated in 6.4. Java 8+ is required, so this method always returns {@code true}.
*/
@@ -142,24 +142,16 @@ public class System2 {
}
/**
- * @deprecated in 5.2. Please use {@link #now()}
- */
- @Deprecated
- public Date newDate() {
- return new Date();
- }
-
- /**
- * @since 5.1
* @return the JVM's default time zone
+ * @since 5.1
*/
public TimeZone getDefaultTimeZone() {
return TimeZone.getDefault();
}
/**
- * @since 5.5
* @see Class#getResource(String)
+ * @since 5.5
*/
public URL getResource(String name) {
return getClass().getResource(name);
@@ -167,6 +159,7 @@ public class System2 {
/**
* Closes the object and throws an {@link java.lang.IllegalStateException} on error.
+ *
* @since 5.1
*/
public void close(AutoCloseable closeable) {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java
index 690509a8daa..9b407ba2a3d 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java
@@ -22,10 +22,10 @@ package org.sonar.scanner.bootstrap;
import java.time.Clock;
import java.util.List;
import java.util.Map;
-import org.sonar.api.SonarEdition;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.Plugin;
+import org.sonar.api.SonarEdition;
import org.sonar.api.SonarQubeSide;
import org.sonar.api.SonarQubeVersion;
import org.sonar.api.internal.MetadataLoader;
@@ -78,9 +78,20 @@ public class GlobalContainer extends ComponentContainer {
addBootstrapComponents();
}
+ private static void checkJavaVersion() {
+ try {
+ String.class.getMethod("isBlank");
+ } catch (NoSuchMethodException e) {
+ LOG.warn("SonarQube scanners will require Java 11+ starting on next version");
+ }
+ }
+
private void addBootstrapComponents() {
Version apiVersion = MetadataLoader.loadVersion(System2.INSTANCE);
SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE);
+ if (edition != SonarEdition.SONARCLOUD) {
+ checkJavaVersion();
+ }
LOG.debug("{} {}", edition.getLabel(), apiVersion);
add(
// plugins