From efff409c5850df93e9fb4f6123fd2818353668b9 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Tue, 4 Oct 2016 14:46:47 +0200 Subject: [PATCH] Fix Quality flaws, including handling of InterruptedException --- .../org/sonar/process/monitor/Monitor.java | 18 +++++++++----- .../org/sonar/process/monitor/ProcessRef.java | 9 +++---- .../main/java/org/sonar/application/App.java | 4 ++-- .../org/sonar/application/PropsBuilder.java | 24 ++++++++++--------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/Monitor.java b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/Monitor.java index 6b62cafd60c..182155ff9fb 100644 --- a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/Monitor.java +++ b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/Monitor.java @@ -82,7 +82,7 @@ public class Monitor { * @throws java.lang.IllegalStateException if already started or if at least one process failed to start. In this case * all processes are terminated. No need to execute {@link #stop()} */ - public void start(List commands) { + public void start(List commands) throws InterruptedException { if (commands.isEmpty()) { throw new IllegalArgumentException("At least one command is required"); } @@ -101,7 +101,7 @@ public class Monitor { startProcesses(); } - private void startProcesses() { + private void startProcesses() throws InterruptedException { // do no start any child process if not in state INIT or RESTARTING (a stop could be in progress too) if (lifecycle.tryToMoveTo(State.STARTING)) { resetFileSystem(); @@ -137,14 +137,14 @@ public class Monitor { } } - private void startAndMonitorProcesses() { + private void startAndMonitorProcesses() throws InterruptedException{ File tempDir = fileSystem.getTempDir(); this.launcher = new JavaProcessLauncher(TIMEOUTS, tempDir); for (JavaCommand command : javaCommands) { try { ProcessRef processRef = launcher.launch(command); monitor(processRef); - } catch (RuntimeException e) { + } catch (InterruptedException | RuntimeException e) { // fail to start or to monitor stop(); throw e; @@ -152,7 +152,7 @@ public class Monitor { } } - private void monitor(ProcessRef processRef) { + private void monitor(ProcessRef processRef) throws InterruptedException { // physically watch if process is alive WatcherThread watcherThread = new WatcherThread(processRef, this); watcherThread.start(); @@ -283,7 +283,13 @@ public class Monitor { @Override public void run() { stopProcesses(); - startProcesses(); + try { + startProcesses(); + } catch (InterruptedException e) { + // Startup was interrupted. Processes are being stopped asynchronously. + // Restoring the interruption state. + Thread.currentThread().interrupt(); + } } } diff --git a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/ProcessRef.java b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/ProcessRef.java index d3523ed2ed4..83d8bb14c30 100644 --- a/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/ProcessRef.java +++ b/server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/ProcessRef.java @@ -58,18 +58,14 @@ class ProcessRef { return commands; } - void waitForUp() { + void waitForUp() throws InterruptedException { boolean up = false; while (!up) { if (isStopped()) { throw new MessageException(String.format("%s failed to start", this)); } up = commands.isUp(); - try { - Thread.sleep(200L); - } catch (InterruptedException e) { - throw new IllegalStateException(String.format("Interrupted while waiting for %s to be up", this), e); - } + Thread.sleep(200L); } } @@ -98,6 +94,7 @@ class ProcessRef { } catch (InterruptedException e) { // can't wait for the termination of process. Let's assume it's down. LoggerFactory.getLogger(getClass()).warn(String.format("Interrupted while stopping process %s", key), e); + Thread.currentThread().interrupt(); } } ProcessUtils.closeStreams(process); 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 059e81c0feb..7ec6052e183 100644 --- a/sonar-application/src/main/java/org/sonar/application/App.java +++ b/sonar-application/src/main/java/org/sonar/application/App.java @@ -48,7 +48,7 @@ public class App implements Stoppable { this.monitor = monitor; } - public void start(Props props) { + public void start(Props props) throws InterruptedException { monitor.start(createCommands(props)); monitor.awaitTermination(); } @@ -134,7 +134,7 @@ public class App implements Stoppable { return FilenameUtils.concat(dir.getAbsolutePath(), "*"); } - public static void main(String[] args) throws Exception { + public static void main(String[] args) throws InterruptedException { CommandLineParser cli = new CommandLineParser(); Properties rawProperties = cli.parseArguments(args); Props props = new PropsBuilder(rawProperties, new JdbcSettings()).build(); diff --git a/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java b/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java index 1e2d25778e2..6101a4e039b 100644 --- a/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java +++ b/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java @@ -27,7 +27,6 @@ import java.io.Reader; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.Properties; -import org.apache.commons.io.IOUtils; import org.sonar.process.ConfigurationUtils; import org.sonar.process.ProcessProperties; import org.sonar.process.Props; @@ -44,14 +43,14 @@ class PropsBuilder { this.homeDir = homeDir; } - PropsBuilder(Properties rawProperties, JdbcSettings jdbcSettings) throws URISyntaxException { + PropsBuilder(Properties rawProperties, JdbcSettings jdbcSettings) { this(rawProperties, jdbcSettings, detectHomeDir()); } /** * Load optional conf/sonar.properties, interpolates environment variables */ - Props build() throws IOException { + Props build() { Properties p = loadPropertiesFile(homeDir); p.putAll(rawProperties); p.setProperty(ProcessProperties.PATH_HOME, homeDir.getAbsolutePath()); @@ -69,20 +68,23 @@ class PropsBuilder { return props; } - static File detectHomeDir() throws URISyntaxException { - File appJar = new File(PropsBuilder.class.getProtectionDomain().getCodeSource().getLocation().toURI()); - return appJar.getParentFile().getParentFile(); + static File detectHomeDir() { + try { + File appJar = new File(PropsBuilder.class.getProtectionDomain().getCodeSource().getLocation().toURI()); + return appJar.getParentFile().getParentFile(); + } catch (URISyntaxException e) { + throw new IllegalStateException("Cannot detect path of main jar file", e); + } } - private static Properties loadPropertiesFile(File homeDir) throws IOException { + private static Properties loadPropertiesFile(File homeDir) { Properties p = new Properties(); File propsFile = new File(homeDir, "conf/sonar.properties"); if (propsFile.exists()) { - Reader reader = new InputStreamReader(new FileInputStream(propsFile), StandardCharsets.UTF_8); - try { + try (Reader reader = new InputStreamReader(new FileInputStream(propsFile), StandardCharsets.UTF_8)) { p.load(reader); - } finally { - IOUtils.closeQuietly(reader); + } catch (IOException e) { + throw new IllegalStateException("Cannot open file " + propsFile, e); } } return p; -- 2.39.5