private File buildPropertiesFile(JavaCommand javaCommand) { File propertiesFile = null; try { propertiesFile = File.createTempFile("sq-process", "properties", tempDir); Properties props = new Properties(); props.putAll(javaCommand.getArguments()); props.setProperty(PROPERTY_PROCESS_KEY, javaCommand.getProcessId().getKey()); props.setProperty(PROPERTY_PROCESS_INDEX, Integer.toString(javaCommand.getProcessId().getIpcIndex())); props.setProperty(PROPERTY_TERMINATION_TIMEOUT_MS, "60000"); props.setProperty(PROPERTY_SHARED_PATH, tempDir.getAbsolutePath()); try (OutputStream out = new FileOutputStream(propertiesFile)) { props.store(out, format("Temporary properties file for command [%s]", javaCommand.getProcessId().getKey())); } return propertiesFile; } catch (Exception e) { throw new IllegalStateException("Cannot write temporary settings to " + propertiesFile, e); } }
private <T extends JvmOptions> ProcessBuilder create(JavaCommand<T> javaCommand) { List<String> commands = new ArrayList<>(); commands.add(buildJavaPath()); commands.addAll(javaCommand.getJvmOptions().getAll()); commands.addAll(buildClasspath(javaCommand)); commands.add(javaCommand.getClassName()); if (javaCommand.getReadsArgumentsFromFile()) { commands.add(buildPropertiesFile(javaCommand).getAbsolutePath()); } else { javaCommand.getArguments().forEach((key, value) -> { if (value != null && !value.isEmpty()) { commands.add("-E" + key + "=" + value); } }); } return create(javaCommand, commands); }
@Override public String toString() { return "JavaCommand{" + "workDir=" + getWorkDir() + ", jvmOptions=" + jvmOptions + ", className='" + className + '\'' + ", classpath=" + classpath + ", arguments=" + getArguments() + ", envVariables=" + getEnvVariables() + ", suppressedEnvVariables=" + getSuppressedEnvVariables() + '}'; } }
@Test public void createCeCommand_returns_command_for_default_settings() { JavaCommand command = newFactory(new Properties()).createCeCommand(); assertThat(command.getClassName()).isEqualTo("org.sonar.ce.app.CeServer"); assertThat(command.getWorkDir().getAbsolutePath()).isEqualTo(homeDir.getAbsolutePath()); assertThat(command.getClasspath()) .containsExactly("./lib/common/*"); assertThat(command.getJvmOptions().getAll()) // enforced values .contains("-Djava.awt.headless=true", "-Dfile.encoding=UTF-8") // default settings .contains("-Djava.io.tmpdir=" + tempDir.getAbsolutePath(), "-Dfile.encoding=UTF-8") .contains("-Xmx512m", "-Xms128m", "-XX:+HeapDumpOnOutOfMemoryError"); assertThat(command.getProcessId()).isEqualTo(ProcessId.COMPUTE_ENGINE); assertThat(command.getEnvVariables()) .isNotEmpty(); assertThat(command.getArguments()) // default settings .contains(entry("sonar.web.javaOpts", "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError")) .contains(entry("sonar.cluster.enabled", "false")); assertThat(command.getSuppressedEnvVariables()).containsOnly("JAVA_TOOL_OPTIONS"); }
@Test public void createWebCommand_returns_command_for_default_settings() { JavaCommand command = newFactory(new Properties()).createWebCommand(true); assertThat(command.getClassName()).isEqualTo("org.sonar.server.app.WebServer"); assertThat(command.getWorkDir().getAbsolutePath()).isEqualTo(homeDir.getAbsolutePath()); assertThat(command.getClasspath()) .containsExactly("./lib/common/*"); assertThat(command.getJvmOptions().getAll()) // enforced values .contains("-Djava.awt.headless=true", "-Dfile.encoding=UTF-8") // default settings .contains("-Djava.io.tmpdir=" + tempDir.getAbsolutePath(), "-Dfile.encoding=UTF-8") .contains("-Xmx512m", "-Xms128m", "-XX:+HeapDumpOnOutOfMemoryError"); assertThat(command.getProcessId()).isEqualTo(ProcessId.WEB_SERVER); assertThat(command.getEnvVariables()) .isNotEmpty(); assertThat(command.getArguments()) // default settings .contains(entry("sonar.web.javaOpts", "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError")) .contains(entry("sonar.cluster.enabled", "false")); assertThat(command.getSuppressedEnvVariables()).containsOnly("JAVA_TOOL_OPTIONS"); }
@Test public void createWebCommand_configures_command_with_overridden_settings() { Properties props = new Properties(); props.setProperty("sonar.web.port", "1234"); props.setProperty("sonar.web.javaOpts", "-Xmx10G"); JavaCommand command = newFactory(props).createWebCommand(true); assertThat(command.getJvmOptions().getAll()) // enforced values .contains("-Djava.awt.headless=true", "-Dfile.encoding=UTF-8") // default settings .contains("-Djava.io.tmpdir=" + tempDir.getAbsolutePath(), "-Dfile.encoding=UTF-8") // overridden values .contains("-Xmx10G") .doesNotContain("-Xms128m", "-XX:+HeapDumpOnOutOfMemoryError"); assertThat(command.getArguments()) // default settings .contains(entry("sonar.web.javaOpts", "-Xmx10G")) .contains(entry("sonar.cluster.enabled", "false")); assertThat(command.getSuppressedEnvVariables()).containsOnly("JAVA_TOOL_OPTIONS"); }
private File buildPropertiesFile(JavaCommand javaCommand) { File propertiesFile = null; try { propertiesFile = File.createTempFile("sq-process", "properties", tempDir); Properties props = new Properties(); props.putAll(javaCommand.getArguments()); props.setProperty(PROPERTY_PROCESS_KEY, javaCommand.getProcessId().getKey()); props.setProperty(PROPERTY_PROCESS_INDEX, Integer.toString(javaCommand.getProcessId().getIpcIndex())); props.setProperty(PROPERTY_TERMINATION_TIMEOUT_MS, "60000"); props.setProperty(PROPERTY_SHARED_PATH, tempDir.getAbsolutePath()); try (OutputStream out = new FileOutputStream(propertiesFile)) { props.store(out, format("Temporary properties file for command [%s]", javaCommand.getProcessId().getKey())); } return propertiesFile; } catch (Exception e) { throw new IllegalStateException("Cannot write temporary settings to " + propertiesFile, e); } }
private <T extends JvmOptions> ProcessBuilder create(JavaCommand<T> javaCommand) { List<String> commands = new ArrayList<>(); commands.add(buildJavaPath()); commands.addAll(javaCommand.getJvmOptions().getAll()); commands.addAll(buildClasspath(javaCommand)); commands.add(javaCommand.getClassName()); if (javaCommand.getReadsArgumentsFromFile()) { commands.add(buildPropertiesFile(javaCommand).getAbsolutePath()); } else { javaCommand.getArguments().forEach((key, value) -> { if (value != null && !value.isEmpty()) { commands.add("-E" + key + "=" + value); } }); } return create(javaCommand, commands); }
@Override public String toString() { return "JavaCommand{" + "workDir=" + getWorkDir() + ", jvmOptions=" + jvmOptions + ", className='" + className + '\'' + ", classpath=" + classpath + ", arguments=" + getArguments() + ", envVariables=" + getEnvVariables() + ", suppressedEnvVariables=" + getSuppressedEnvVariables() + '}'; } }