apply plugin: 'idea' | apply plugin: 'idea' | ||||
apply plugin: 'signing' | apply plugin: 'signing' | ||||
sourceCompatibility = 1.8 | |||||
targetCompatibility = 1.8 | |||||
// do not deploy to Artifactory by default | // do not deploy to Artifactory by default | ||||
artifactoryPublish.skip = true | artifactoryPublish.skip = true | ||||
ext { | ext { | ||||
protobufVersion = '3.11.4' | protobufVersion = '3.11.4' | ||||
// define a method which can be called by project to change Java version to compile to | |||||
configureCompileJavaToVersion = { javaVersion -> | |||||
if ( javaVersion != 11 & javaVersion != 8) { | |||||
throw new InvalidUserDataException("Only Java 8 and 11 are supported") | |||||
} | |||||
if ( javaVersion == 8 ) { | |||||
println "Configuring project ${project.name} to compile to Java ${javaVersion}" | |||||
if (!project.hasProperty('skipJava8Checks')) { | |||||
task ensureDependenciesRunOnJava8(dependsOn: [configurations.compileClasspath]) { | |||||
ext.readJavaMajorVersion = { classFile -> | |||||
classFile.withDataInputStream({ d -> | |||||
if (d.skip(7) == 7) { | |||||
// read the version of the class file | |||||
d.read() | |||||
} else { | |||||
throw new GradleException("Could not read major version from $classFile") | |||||
} | |||||
}) | |||||
} | |||||
doLast { | |||||
[configurations.compileClasspath].each { config -> | |||||
config.resolvedConfiguration.files | |||||
.findAll({ f -> f.name.endsWith("jar") }) | |||||
.each { jarFile -> | |||||
def onlyJava8 = true | |||||
zipTree(jarFile) | |||||
.matching({ | |||||
include "**/*.class" | |||||
// multi-release jar files were introduced with Java 9 => contains only classes targeting Java 9+ | |||||
exclude "META-INF/versions/**" | |||||
// ignore module-info existing in some archives for Java 9 forward compatibility | |||||
exclude "module-info.class" | |||||
}) | |||||
.files | |||||
.each { classFile -> | |||||
int javaMajorVersion = readJavaMajorVersion(classFile) | |||||
if (javaMajorVersion > 52) { | |||||
println "$classFile has been compiled to a more recent version of Java than 8 (java8=52, java11=55, actual=$javaMajorVersion)" | |||||
onlyJava8 = false | |||||
} | |||||
} | |||||
if (!onlyJava8) { | |||||
throw new GradleException("Dependency ${jarFile} in configuration ${config.name} contains class file(s) compiled to a Java version > Java 8 (see logs for details)") | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
compileJava.dependsOn ensureDependenciesRunOnJava8 | |||||
} | |||||
} | |||||
sourceCompatibility = javaVersion | |||||
targetCompatibility = javaVersion | |||||
tasks.withType(JavaCompile) { | |||||
options.compilerArgs.addAll(['--release', javaVersion + '']) | |||||
options.encoding = 'UTF-8' | |||||
} | |||||
} | |||||
} | } | ||||
configureCompileJavaToVersion 11 | |||||
sonarqube { | sonarqube { | ||||
properties { | properties { | ||||
property 'sonar.moduleKey', project.group + ':' + project.name | property 'sonar.moduleKey', project.group + ':' + project.name | ||||
exclude group: 'javax.mail', module: 'mail' | exclude group: 'javax.mail', module: 'mail' | ||||
} | } | ||||
tasks.withType(JavaCompile) { | |||||
options.compilerArgs.addAll(['--release', '8']) | |||||
options.encoding = 'UTF-8' | |||||
} | |||||
tasks.withType(Javadoc) { | tasks.withType(Javadoc) { | ||||
options.addStringOption('Xdoclint:none', '-quiet') | options.addStringOption('Xdoclint:none', '-quiet') | ||||
options.encoding = 'UTF-8' | options.encoding = 'UTF-8' |
testCompile.extendsFrom(compileOnly) | testCompile.extendsFrom(compileOnly) | ||||
} | } | ||||
configureCompileJavaToVersion 8 | |||||
dependencies { | dependencies { | ||||
compile 'com.google.guava:guava' | compile 'com.google.guava:guava' | ||||
compile 'commons-io:commons-io' | compile 'commons-io:commons-io' |
*/ | */ | ||||
package org.sonar.ce.container; | package org.sonar.ce.container; | ||||
import com.google.common.collect.ImmutableList; | |||||
import java.io.File; | import java.io.File; | ||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Set; | |||||
import java.util.concurrent.atomic.AtomicBoolean; | import java.util.concurrent.atomic.AtomicBoolean; | ||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
import org.apache.commons.io.FileUtils; | import org.apache.commons.io.FileUtils; | ||||
@Override | @Override | ||||
public Collection<PluginInfo> getPluginInfos() { | public Collection<PluginInfo> getPluginInfos() { | ||||
checkState(started.get(), NOT_STARTED_YET); | checkState(started.get(), NOT_STARTED_YET); | ||||
return ImmutableList.copyOf(pluginInfosByKeys.values()); | |||||
return Set.copyOf(pluginInfosByKeys.values()); | |||||
} | } | ||||
@Override | @Override |
public class CeJvmOptions extends JvmOptions<CeJvmOptions> { | public class CeJvmOptions extends JvmOptions<CeJvmOptions> { | ||||
public CeJvmOptions(File tmpDir, JavaVersion javaVersion) { | |||||
super(mandatoryOptions(tmpDir, javaVersion)); | |||||
public CeJvmOptions(File tmpDir) { | |||||
super(mandatoryOptions(tmpDir)); | |||||
} | } | ||||
private static Map<String, String> mandatoryOptions(File tmpDir, JavaVersion javaVersion) { | |||||
private static Map<String, String> mandatoryOptions(File tmpDir) { | |||||
Map<String, String> res = new LinkedHashMap<>(3); | Map<String, String> res = new LinkedHashMap<>(3); | ||||
res.put("-Djava.awt.headless=", "true"); | res.put("-Djava.awt.headless=", "true"); | ||||
res.put("-Dfile.encoding=", "UTF-8"); | res.put("-Dfile.encoding=", "UTF-8"); | ||||
res.put("-Djava.io.tmpdir=", tmpDir.getAbsolutePath()); | res.put("-Djava.io.tmpdir=", tmpDir.getAbsolutePath()); | ||||
res.put("-XX:-OmitStackTraceInFastThrow", ""); | res.put("-XX:-OmitStackTraceInFastThrow", ""); | ||||
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 MyBatis | |||||
res.put("--add-opens=java.base/java.util=ALL-UNNAMED", ""); | |||||
return res; | return res; | ||||
} | } | ||||
} | } |
private final Props props; | private final Props props; | ||||
private final File tempDir; | private final File tempDir; | ||||
private final System2 system2; | private final System2 system2; | ||||
private final JavaVersion javaVersion; | |||||
public CommandFactoryImpl(Props props, File tempDir, System2 system2, JavaVersion javaVersion) { | |||||
public CommandFactoryImpl(Props props, File tempDir, System2 system2) { | |||||
this.props = props; | this.props = props; | ||||
this.tempDir = tempDir; | this.tempDir = tempDir; | ||||
this.system2 = system2; | this.system2 = system2; | ||||
this.javaVersion = javaVersion; | |||||
String javaToolOptions = system2.getenv(ENV_VAR_JAVA_TOOL_OPTIONS); | String javaToolOptions = system2.getenv(ENV_VAR_JAVA_TOOL_OPTIONS); | ||||
if (javaToolOptions != null && !javaToolOptions.trim().isEmpty()) { | if (javaToolOptions != null && !javaToolOptions.trim().isEmpty()) { | ||||
LoggerFactory.getLogger(CommandFactoryImpl.class) | LoggerFactory.getLogger(CommandFactoryImpl.class) | ||||
public JavaCommand createWebCommand(boolean leader) { | public JavaCommand createWebCommand(boolean leader) { | ||||
File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey()); | File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey()); | ||||
WebJvmOptions jvmOptions = new WebJvmOptions(tempDir, javaVersion) | |||||
WebJvmOptions jvmOptions = new WebJvmOptions(tempDir) | |||||
.addFromMandatoryProperty(props, WEB_JAVA_OPTS.getKey()) | .addFromMandatoryProperty(props, WEB_JAVA_OPTS.getKey()) | ||||
.addFromMandatoryProperty(props, WEB_JAVA_ADDITIONAL_OPTS.getKey()); | .addFromMandatoryProperty(props, WEB_JAVA_ADDITIONAL_OPTS.getKey()); | ||||
addProxyJvmOptions(jvmOptions); | addProxyJvmOptions(jvmOptions); | ||||
public JavaCommand createCeCommand() { | public JavaCommand createCeCommand() { | ||||
File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey()); | File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey()); | ||||
CeJvmOptions jvmOptions = new CeJvmOptions(tempDir, javaVersion) | |||||
CeJvmOptions jvmOptions = new CeJvmOptions(tempDir) | |||||
.addFromMandatoryProperty(props, CE_JAVA_OPTS.getKey()) | .addFromMandatoryProperty(props, CE_JAVA_OPTS.getKey()) | ||||
.addFromMandatoryProperty(props, CE_JAVA_ADDITIONAL_OPTS.getKey()); | .addFromMandatoryProperty(props, CE_JAVA_ADDITIONAL_OPTS.getKey()); | ||||
addProxyJvmOptions(jvmOptions); | addProxyJvmOptions(jvmOptions); |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2021 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; | |||||
} | |||||
} | |||||
} |
import java.util.Map; | import java.util.Map; | ||||
public class WebJvmOptions extends JvmOptions<WebJvmOptions> { | public class WebJvmOptions extends JvmOptions<WebJvmOptions> { | ||||
public WebJvmOptions(File tmpDir, JavaVersion javaVersion) { | |||||
super(mandatoryOptions(tmpDir, javaVersion)); | |||||
public WebJvmOptions(File tmpDir) { | |||||
super(mandatoryOptions(tmpDir)); | |||||
} | } | ||||
private static Map<String, String> mandatoryOptions(File tmpDir, JavaVersion javaVersion) { | |||||
private static Map<String, String> mandatoryOptions(File tmpDir) { | |||||
Map<String, String> res = new LinkedHashMap<>(3); | Map<String, String> res = new LinkedHashMap<>(3); | ||||
res.put("-Djava.awt.headless=", "true"); | res.put("-Djava.awt.headless=", "true"); | ||||
res.put("-Dfile.encoding=", "UTF-8"); | res.put("-Dfile.encoding=", "UTF-8"); | ||||
res.put("-Djava.io.tmpdir=", tmpDir.getAbsolutePath()); | res.put("-Djava.io.tmpdir=", tmpDir.getAbsolutePath()); | ||||
res.put("-XX:-OmitStackTraceInFastThrow", ""); | res.put("-XX:-OmitStackTraceInFastThrow", ""); | ||||
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 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", ""); | |||||
} | |||||
// 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; | return res; | ||||
} | } | ||||
} | } |
import org.junit.rules.TemporaryFolder; | import org.junit.rules.TemporaryFolder; | ||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
import static org.mockito.Mockito.mock; | |||||
import static org.mockito.Mockito.when; | |||||
public class CeJvmOptionsTest { | public class CeJvmOptionsTest { | ||||
@Rule | @Rule | ||||
public TemporaryFolder temporaryFolder = new TemporaryFolder(); | public TemporaryFolder temporaryFolder = new TemporaryFolder(); | ||||
private File tmpDir; | private File tmpDir; | ||||
private JavaVersion javaVersion = mock(JavaVersion.class); | |||||
private CeJvmOptions underTest; | private CeJvmOptions underTest; | ||||
@Before | @Before | ||||
} | } | ||||
@Test | @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(), "-XX:-OmitStackTraceInFastThrow"); | |||||
} | |||||
@Test | |||||
public void constructor_sets_mandatory_JVM_options_for_java11() { | |||||
when(javaVersion.isAtLeastJava11()).thenReturn(true); | |||||
underTest = new CeJvmOptions(tmpDir, javaVersion); | |||||
public void constructor_sets_mandatory_JVM_options() { | |||||
underTest = new CeJvmOptions(tmpDir); | |||||
assertThat(underTest.getAll()).containsExactly( | assertThat(underTest.getAll()).containsExactly( | ||||
"-Djava.awt.headless=true", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=" + tmpDir.getAbsolutePath(), "-XX:-OmitStackTraceInFastThrow", | "-Djava.awt.headless=true", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=" + tmpDir.getAbsolutePath(), "-XX:-OmitStackTraceInFastThrow", | ||||
"--add-opens=java.base/java.util=ALL-UNNAMED"); | "--add-opens=java.base/java.util=ALL-UNNAMED"); |
public TemporaryFolder temp = new TemporaryFolder(); | public TemporaryFolder temp = new TemporaryFolder(); | ||||
private System2 system2 = Mockito.mock(System2.class); | private System2 system2 = Mockito.mock(System2.class); | ||||
private JavaVersion javaVersion = Mockito.mock(JavaVersion.class); | |||||
private File homeDir; | private File homeDir; | ||||
private File tempDir; | private File tempDir; | ||||
private File logsDir; | private File logsDir; | ||||
public void constructor_logs_no_warning_if_env_variable_JAVA_TOOL_OPTIONS_is_not_set() { | public void constructor_logs_no_warning_if_env_variable_JAVA_TOOL_OPTIONS_is_not_set() { | ||||
attachMemoryAppenderToLoggerOf(CommandFactoryImpl.class); | attachMemoryAppenderToLoggerOf(CommandFactoryImpl.class); | ||||
new CommandFactoryImpl(new Props(new Properties()), tempDir, system2, javaVersion); | |||||
new CommandFactoryImpl(new Props(new Properties()), tempDir, system2); | |||||
assertThat(listAppender.getLogs()).isEmpty(); | assertThat(listAppender.getLogs()).isEmpty(); | ||||
} | } | ||||
when(system2.getenv("JAVA_TOOL_OPTIONS")).thenReturn("sds"); | when(system2.getenv("JAVA_TOOL_OPTIONS")).thenReturn("sds"); | ||||
attachMemoryAppenderToLoggerOf(CommandFactoryImpl.class); | attachMemoryAppenderToLoggerOf(CommandFactoryImpl.class); | ||||
new CommandFactoryImpl(new Props(new Properties()), tempDir, system2, javaVersion); | |||||
new CommandFactoryImpl(new Props(new Properties()), tempDir, system2); | |||||
assertThat(listAppender.getLogs()) | assertThat(listAppender.getLogs()) | ||||
.extracting(ILoggingEvent::getMessage) | .extracting(ILoggingEvent::getMessage) | ||||
when(system2.getenv("ES_JAVA_OPTS")).thenReturn("xyz"); | when(system2.getenv("ES_JAVA_OPTS")).thenReturn("xyz"); | ||||
attachMemoryAppenderToLoggerOf(CommandFactoryImpl.class); | attachMemoryAppenderToLoggerOf(CommandFactoryImpl.class); | ||||
new CommandFactoryImpl(new Props(new Properties()), tempDir, system2, javaVersion); | |||||
new CommandFactoryImpl(new Props(new Properties()), tempDir, system2); | |||||
assertThat(listAppender.getLogs()) | assertThat(listAppender.getLogs()) | ||||
.extracting(ILoggingEvent::getMessage) | .extracting(ILoggingEvent::getMessage) | ||||
ServiceLoaderWrapper serviceLoaderWrapper = mock(ServiceLoaderWrapper.class); | ServiceLoaderWrapper serviceLoaderWrapper = mock(ServiceLoaderWrapper.class); | ||||
when(serviceLoaderWrapper.load()).thenReturn(ImmutableSet.of()); | when(serviceLoaderWrapper.load()).thenReturn(ImmutableSet.of()); | ||||
new ProcessProperties(serviceLoaderWrapper).completeDefaults(props); | new ProcessProperties(serviceLoaderWrapper).completeDefaults(props); | ||||
return new CommandFactoryImpl(props, tempDir, system2, javaVersion); | |||||
return new CommandFactoryImpl(props, tempDir, system2); | |||||
} | } | ||||
private <T> void attachMemoryAppenderToLoggerOf(Class<T> loggerClass) { | private <T> void attachMemoryAppenderToLoggerOf(Class<T> loggerClass) { |
import org.junit.rules.TemporaryFolder; | import org.junit.rules.TemporaryFolder; | ||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
import static org.mockito.Mockito.mock; | |||||
import static org.mockito.Mockito.when; | |||||
public class WebJvmOptionsTest { | public class WebJvmOptionsTest { | ||||
@Rule | @Rule | ||||
public TemporaryFolder temporaryFolder = new TemporaryFolder(); | public TemporaryFolder temporaryFolder = new TemporaryFolder(); | ||||
private File tmpDir; | private File tmpDir; | ||||
private JavaVersion javaVersion = mock(JavaVersion.class); | |||||
private WebJvmOptions underTest; | private WebJvmOptions underTest; | ||||
@Before | @Before | ||||
} | } | ||||
@Test | @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(), "-XX:-OmitStackTraceInFastThrow"); | |||||
} | |||||
@Test | |||||
public void constructor_sets_mandatory_JVM_options_for_java11() { | |||||
when(javaVersion.isAtLeastJava11()).thenReturn(true); | |||||
underTest = new WebJvmOptions(tmpDir, javaVersion); | |||||
public void constructor_sets_mandatory_JVM_options() { | |||||
underTest = new WebJvmOptions(tmpDir); | |||||
assertThat(underTest.getAll()).containsExactly( | assertThat(underTest.getAll()).containsExactly( | ||||
"-Djava.awt.headless=true", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=" + tmpDir.getAbsolutePath(), "-XX:-OmitStackTraceInFastThrow", | "-Djava.awt.headless=true", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=" + tmpDir.getAbsolutePath(), "-XX:-OmitStackTraceInFastThrow", |
} | } | ||||
return (int) deliveries.stream() | return (int) deliveries.stream() | ||||
.filter(t -> !t.getRecipientEmail().trim().isEmpty()) | |||||
.filter(t -> !t.getRecipientEmail().isBlank()) | |||||
.map(t -> { | .map(t -> { | ||||
EmailMessage emailMessage = format(t.getNotification()); | EmailMessage emailMessage = format(t.getNotification()); | ||||
if (emailMessage != null) { | if (emailMessage != null) { |
.filter(Objects::nonNull) | .filter(Objects::nonNull) | ||||
.findFirst(); | .findFirst(); | ||||
// may occur in case of plugin downgrade | // may occur in case of plugin downgrade | ||||
if (!res.isPresent()) { | |||||
if (res.isEmpty()) { | |||||
return Optional.ofNullable(dbRulesByDbDeprecatedKey.get(ruleKey)); | return Optional.ofNullable(dbRulesByDbDeprecatedKey.get(ruleKey)); | ||||
} | } | ||||
return res; | return res; |
*/ | */ | ||||
package org.sonar.application; | package org.sonar.application; | ||||
import org.sonar.api.SonarEdition; | |||||
import org.sonar.api.internal.MetadataLoader; | |||||
import org.sonar.api.utils.log.Loggers; | import org.sonar.api.utils.log.Loggers; | ||||
import org.sonar.application.command.CommandFactory; | import org.sonar.application.command.CommandFactory; | ||||
import org.sonar.application.command.CommandFactoryImpl; | import org.sonar.application.command.CommandFactoryImpl; | ||||
import org.sonar.application.command.JavaVersion; | |||||
import org.sonar.application.config.AppSettings; | import org.sonar.application.config.AppSettings; | ||||
import org.sonar.application.config.AppSettingsLoader; | import org.sonar.application.config.AppSettingsLoader; | ||||
import org.sonar.application.config.AppSettingsLoaderImpl; | import org.sonar.application.config.AppSettingsLoaderImpl; | ||||
import org.sonar.process.System2; | import org.sonar.process.System2; | ||||
import org.sonar.process.SystemExit; | import org.sonar.process.SystemExit; | ||||
import static com.google.common.base.Preconditions.checkState; | |||||
import static org.sonar.application.config.SonarQubeVersionHelper.getSonarqubeVersion; | import static org.sonar.application.config.SonarQubeVersionHelper.getSonarqubeVersion; | ||||
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NAME; | import static org.sonar.process.ProcessProperties.Property.CLUSTER_NAME; | ||||
public class App { | public class App { | ||||
private final SystemExit systemExit = new SystemExit(); | private final SystemExit systemExit = new SystemExit(); | ||||
private final JavaVersion javaVersion; | |||||
private StopRequestWatcher stopRequestWatcher = null; | private StopRequestWatcher stopRequestWatcher = null; | ||||
private StopRequestWatcher hardStopRequestWatcher = null; | private StopRequestWatcher hardStopRequestWatcher = null; | ||||
public App(JavaVersion javaVersion) { | |||||
this.javaVersion = javaVersion; | |||||
} | |||||
public void start(String[] cliArguments) { | public void start(String[] cliArguments) { | ||||
AppSettingsLoader settingsLoader = new AppSettingsLoaderImpl(System2.INSTANCE, cliArguments, new ServiceLoaderWrapper()); | AppSettingsLoader settingsLoader = new AppSettingsLoaderImpl(System2.INSTANCE, cliArguments, new ServiceLoaderWrapper()); | ||||
AppLogging logging = new AppLogging(settings); | AppLogging logging = new AppLogging(settings); | ||||
logging.configure(); | logging.configure(); | ||||
AppFileSystem fileSystem = new AppFileSystem(settings); | AppFileSystem fileSystem = new AppFileSystem(settings); | ||||
checkJavaVersion(); | |||||
try (AppState appState = new AppStateFactory(settings).create()) { | try (AppState appState = new AppStateFactory(settings).create()) { | ||||
appState.registerSonarQubeVersion(getSonarqubeVersion()); | appState.registerSonarQubeVersion(getSonarqubeVersion()); | ||||
appState.registerClusterName(settings.getProps().nonNullValue(CLUSTER_NAME.getKey())); | appState.registerClusterName(settings.getProps().nonNullValue(CLUSTER_NAME.getKey())); | ||||
AppReloader appReloader = new AppReloaderImpl(settingsLoader, fileSystem, appState, logging); | AppReloader appReloader = new AppReloaderImpl(settingsLoader, fileSystem, appState, logging); | ||||
fileSystem.reset(); | fileSystem.reset(); | ||||
CommandFactory commandFactory = new CommandFactoryImpl(settings.getProps(), fileSystem.getTempDir(), System2.INSTANCE, JavaVersion.INSTANCE); | |||||
CommandFactory commandFactory = new CommandFactoryImpl(settings.getProps(), fileSystem.getTempDir(), System2.INSTANCE); | |||||
try (ProcessLauncher processLauncher = new ProcessLauncherImpl(fileSystem.getTempDir())) { | try (ProcessLauncher processLauncher = new ProcessLauncherImpl(fileSystem.getTempDir())) { | ||||
Scheduler scheduler = new SchedulerImpl(settings, appReloader, commandFactory, processLauncher, appState); | Scheduler scheduler = new SchedulerImpl(settings, appReloader, commandFactory, processLauncher, appState); | ||||
systemExit.exit(0); | systemExit.exit(0); | ||||
} | } | ||||
private void checkJavaVersion() { | |||||
if (MetadataLoader.loadEdition(org.sonar.api.utils.System2.INSTANCE) == SonarEdition.SONARCLOUD) { | |||||
return; | |||||
} | |||||
checkState(javaVersion.isAtLeastJava11(), "SonarQube requires Java 11 to run"); | |||||
} | |||||
public static void main(String[] args) throws Exception { | public static void main(String[] args) throws Exception { | ||||
new App(JavaVersion.INSTANCE).start(args); | |||||
new App().start(args); | |||||
} | } | ||||
private class ShutdownHook extends Thread { | private class ShutdownHook extends Thread { |
} | } | ||||
} | } | ||||
configureCompileJavaToVersion 8 | |||||
dependencies { | dependencies { | ||||
compileOnly 'com.google.code.findbugs:jsr305' | compileOnly 'com.google.code.findbugs:jsr305' | ||||
} | } |
} | } | ||||
} | } | ||||
configureCompileJavaToVersion 8 | |||||
dependencies { | dependencies { | ||||
// please keep list ordered | // please keep list ordered | ||||
} | } | ||||
} | } | ||||
configureCompileJavaToVersion 8 | |||||
dependencies { | dependencies { | ||||
// please keep list ordered | // please keep list ordered | ||||
} | } | ||||
} | } | ||||
configureCompileJavaToVersion 8 | |||||
dependencies { | dependencies { | ||||
// please keep the list grouped by configuration and ordered by name | // please keep the list grouped by configuration and ordered by name | ||||
} | } | ||||
} | } | ||||
configureCompileJavaToVersion 8 | |||||
apply plugin: 'com.github.johnrengelman.shadow' | apply plugin: 'com.github.johnrengelman.shadow' | ||||
dependencies { | dependencies { |
private Date loadAnalysisDate() { | private Date loadAnalysisDate() { | ||||
Optional<String> value = settings.get(CoreProperties.PROJECT_DATE_PROPERTY); | Optional<String> value = settings.get(CoreProperties.PROJECT_DATE_PROPERTY); | ||||
if (!value.isPresent()) { | |||||
if (value.isEmpty()) { | |||||
return Date.from(clock.instant()); | return Date.from(clock.instant()); | ||||
} | } | ||||
try { | try { |
import org.sonar.api.SonarRuntime; | import org.sonar.api.SonarRuntime; | ||||
import org.sonar.api.internal.MetadataLoader; | import org.sonar.api.internal.MetadataLoader; | ||||
import org.sonar.api.internal.SonarRuntimeImpl; | import org.sonar.api.internal.SonarRuntimeImpl; | ||||
import org.sonar.api.notifications.AnalysisWarnings; | |||||
import org.sonar.api.utils.MessageException; | import org.sonar.api.utils.MessageException; | ||||
import org.sonar.api.utils.System2; | import org.sonar.api.utils.System2; | ||||
import org.sonar.api.utils.UriReader; | import org.sonar.api.utils.UriReader; | ||||
addBootstrapComponents(); | addBootstrapComponents(); | ||||
} | } | ||||
private static void checkJavaVersion(AnalysisWarnings analysisWarnings) { | |||||
try { | |||||
String.class.getMethod("isBlank"); | |||||
} catch (NoSuchMethodException e) { | |||||
LOG.warn("SonarScanner will require Java 11 to run, starting in SonarQube 9.x"); | |||||
analysisWarnings.addUnique("SonarScanner will require Java 11 to run, starting in SonarQube 9.x. Please upgrade the version of Java that executes the scanner and " + | |||||
"refer to <a href=\"/documentation/analysis/analysis-with-java-11/\" target=\"_blank\">the documentation</a> if needed."); | |||||
} | |||||
} | |||||
private void addBootstrapComponents() { | private void addBootstrapComponents() { | ||||
Version apiVersion = MetadataLoader.loadVersion(System2.INSTANCE); | Version apiVersion = MetadataLoader.loadVersion(System2.INSTANCE); | ||||
SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); | SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); | ||||
DefaultAnalysisWarnings analysisWarnings = new DefaultAnalysisWarnings(System2.INSTANCE); | DefaultAnalysisWarnings analysisWarnings = new DefaultAnalysisWarnings(System2.INSTANCE); | ||||
if (edition != SonarEdition.SONARCLOUD) { | |||||
checkJavaVersion(analysisWarnings); | |||||
} | |||||
LOG.debug("{} {}", edition.getLabel(), apiVersion); | LOG.debug("{} {}", edition.getLabel(), apiVersion); | ||||
add( | add( | ||||
// plugins | // plugins |
} | } | ||||
} | } | ||||
configureCompileJavaToVersion 8 | |||||
dependencies { | dependencies { | ||||
// please keep the list ordered | // please keep the list ordered | ||||
compile 'com.google.code.gson:gson' | compile 'com.google.code.gson:gson' |
} | } | ||||
} | } | ||||
configureCompileJavaToVersion 8 | |||||
dependencies { | dependencies { | ||||
// please keep list ordered | // please keep list ordered | ||||
} | } | ||||
} | } | ||||
configureCompileJavaToVersion 8 | |||||
configurations { | configurations { | ||||
testCompile.extendsFrom(compileOnly) | testCompile.extendsFrom(compileOnly) | ||||
} | } |