Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
public class JavaRunner {
private static final Logger LOG = LoggerFactory.getLogger(JavaRunner.class);

static final String JRE_VERSION_ERROR = "The version of the custom JRE provided to the SonarScanner using the 'sonar.scanner.javaExePath' parameter is incompatible " +
"with your SonarQube target. You may need to upgrade the version of Java that executes the scanner. " +
"Refer to https://docs.sonarsource.com/sonarqube-community-build/analyzing-source-code/scanners/scanner-environment/general-requirements/ for more details.";

private final Path javaExecutable;
private final JreCacheHit jreCacheHit;

Expand All @@ -56,18 +60,19 @@ public boolean execute(List<String> args, @Nullable String input, Consumer<Strin
LOG.debug("Executing: {}", String.join(" ", command));
}
Process process = new ProcessBuilder(command).start();
if (input != null) {
try (var stdin = process.getOutputStream(); var osw = new OutputStreamWriter(stdin, StandardCharsets.UTF_8)) {
osw.write(input);
}
}
var stdoutConsummer = new StreamGobbler(process.getInputStream(), stdOutConsummer);
var stdErrConsummer = new StreamGobbler(process.getErrorStream(), stderr -> LOG.error("[stderr] {}", stderr));
stdErrConsummer.start();
stdoutConsummer.start();
if (input != null && process.isAlive()) {
try (var stdin = process.getOutputStream(); var osw = new OutputStreamWriter(stdin, StandardCharsets.UTF_8)) {
osw.write(input);
}
}
var exitCode = process.waitFor();
stdoutConsummer.join();
stdErrConsummer.join();

if (exitCode != 0) {
LOG.debug("Java command exited with code {}", process.exitValue());
return false;
Expand Down Expand Up @@ -95,7 +100,13 @@ public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
@Override
public void run() {
new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.forEach(consumer);
.forEach(line -> {
consumer.accept(line);
if (line.contains("UnsupportedClassVersionError")) {
LOG.error(JRE_VERSION_ERROR);
}
});
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -403,15 +403,15 @@ void should_set_deprecated_ssl_properties() {

when(httpConfig.getSslConfig())
.thenReturn(new SslConfig(
new CertificateStore(Paths.get("some/keystore.p12"), "keystorePass"),
new CertificateStore(Paths.get("some/truststore.p12"), "truststorePass")));
new CertificateStore(Paths.get("some", "keystore.p12"), "keystorePass"),
new CertificateStore(Paths.get("some", "truststore.p12"), "truststorePass")));

underTest.adaptDeprecatedPropertiesForInProcessBootstrapping(Map.of(), httpConfig);

assertThat(System.getProperties()).contains(
entry("javax.net.ssl.keyStore", "some/keystore.p12"),
entry("javax.net.ssl.keyStore", Paths.get("some", "keystore.p12").toString()),
entry("javax.net.ssl.keyStorePassword", "keystorePass"),
entry("javax.net.ssl.trustStore", "some/truststore.p12"),
entry("javax.net.ssl.trustStore", Paths.get("some", "truststore.p12").toString()),
entry("javax.net.ssl.trustStorePassword", "truststorePass"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.event.Level;
import testutils.LogTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.sonarsource.scanner.lib.internal.facade.forked.JavaRunner.JRE_VERSION_ERROR;

class JavaRunnerTest {

Expand Down Expand Up @@ -59,6 +62,15 @@ void execute_shouldLogProcessStdError() {
assertThat(logTester.logs(Level.ERROR)).isNotEmpty().allMatch(s -> s.startsWith("[stderr] "));
}

@Test
void execute_shouldLogProcessStdError_and_skip_writing_to_stdin_when_process_fails_early() {
JavaRunner runner = new JavaRunner(Paths.get("java"), JreCacheHit.DISABLED);
List<String> command = List.of("-xyz");
assertThat(runner.execute(command, "test", stdOut::add)).isFalse();

assertThat(logTester.logs(Level.ERROR)).anyMatch(s -> s.startsWith("[stderr] Unrecognized option: -xyz"));
}

@Test
void execute_whenInvalidRunner_shouldFail() {
JavaRunner runner = new JavaRunner(Paths.get("invalid-runner"), JreCacheHit.DISABLED);
Expand All @@ -75,4 +87,24 @@ void execute_shouldReturnFalseWhenNonZeroExitCode() {
assertThat(runner.execute(command, null, stdOut::add)).isFalse();
}

@Test
@EnabledOnOs(OS.WINDOWS)
void execute_shouldLogUnsupportedClassVersionError_whenOsIsWindows() {
JavaRunner runner = new JavaRunner(Paths.get("cmd.exe"), JreCacheHit.DISABLED);
List<String> command = List.of("/c", "echo UnsupportedClassVersionError 1>&2");

assertThat(runner.execute(command, null, stdOut::add)).isTrue();
assertThat(logTester.logs(Level.ERROR)).contains(JRE_VERSION_ERROR);
}

@Test
@EnabledOnOs(OS.LINUX)
void execute_shouldLogUnsupportedClassVersionError_whenOsIsLinux() {
JavaRunner runner = new JavaRunner(Paths.get("sh"), JreCacheHit.DISABLED);
List<String> command = List.of("-c", ">&2 echo UnsupportedClassVersionError");

assertThat(runner.execute(command, null, stdOut::add)).isTrue();
assertThat(logTester.logs(Level.ERROR)).contains(JRE_VERSION_ERROR);
}

}
Loading