@@ -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; | |||
} | |||
} |
@@ -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); |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |
@@ -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) { |
@@ -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"); | |||
} | |||
} |
@@ -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 { |
@@ -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); |
@@ -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) { |
@@ -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 |