diff options
4 files changed, 124 insertions, 7 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java index 7c05398b27d..3de296ae89b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java @@ -20,9 +20,11 @@ package org.sonar.batch.bootstrapper; import com.google.common.collect.Lists; +import org.slf4j.LoggerFactory; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.batch.bootstrap.BootstrapModule; import org.sonar.batch.bootstrap.Module; +import org.sonar.core.PicoUtils; import java.util.Arrays; import java.util.List; @@ -69,6 +71,8 @@ public final class Batch { Module bootstrapModule = new BootstrapModule(projectReactor, components.toArray(new Object[components.size()])).init(); try { bootstrapModule.start(); + } catch (RuntimeException e) { + PicoUtils.handleStartupException(e, LoggerFactory.getLogger(getClass())); } finally { try { bootstrapModule.stop(); diff --git a/sonar-core/src/main/java/org/sonar/core/PicoUtils.java b/sonar-core/src/main/java/org/sonar/core/PicoUtils.java new file mode 100644 index 00000000000..3e765df7632 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/PicoUtils.java @@ -0,0 +1,50 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core; + +import com.google.common.base.Throwables; +import org.picocontainer.PicoLifecycleException; +import org.slf4j.Logger; + +public final class PicoUtils { + + private PicoUtils() { + } + + public static Throwable sanitizeException(RuntimeException t) { + Throwable result = t; + Throwable cause = t.getCause(); + if (t instanceof PicoLifecycleException && cause != null) { + if ("wrapper".equals(cause.getMessage()) && cause.getCause() != null) { + result = cause.getCause(); + } else { + result = cause; + } + + } + return result; + } + + public static void handleStartupException(RuntimeException t, Logger logger) { + Throwable cause = sanitizeException(t); + logger.error(cause.getMessage()); + Throwables.propagate(cause); + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/PicoUtilsTest.java b/sonar-core/src/test/java/org/sonar/core/PicoUtilsTest.java new file mode 100644 index 00000000000..40760a1c62a --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/PicoUtilsTest.java @@ -0,0 +1,64 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core; + +import org.hamcrest.core.Is; +import org.junit.Test; +import org.picocontainer.PicoLifecycleException; +import org.sonar.api.platform.ComponentContainer; + +import static org.junit.Assert.assertThat; + +public class PicoUtilsTest { + @Test + public void shouldSanitizePicoLifecycleException() { + Throwable th = PicoUtils.sanitizeException(newPicoLifecycleException()); + + assertThat(th, Is.is(IllegalStateException.class)); + assertThat(th.getMessage(), Is.is("A good reason to fail")); + } + + @Test + public void shouldNotSanitizeOtherExceptions() { + Throwable th = PicoUtils.sanitizeException(new IllegalArgumentException("foo")); + + assertThat(th, Is.is(IllegalArgumentException.class)); + assertThat(th.getMessage(), Is.is("foo")); + } + + + private PicoLifecycleException newPicoLifecycleException() { + ComponentContainer componentContainer = new ComponentContainer(); + componentContainer.addSingleton(FailureComponent.class); + try { + componentContainer.startComponents(); + return null; + + } catch (PicoLifecycleException e) { + return e; + } + } + + public static class FailureComponent { + public void start() { + throw new IllegalStateException("A good reason to fail"); + } + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index e7591b7324e..8338c83a42d 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -35,7 +35,7 @@ import org.sonar.api.rules.XMLRuleParser; import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.IocContainer; import org.sonar.api.utils.TimeProfiler; -import org.sonar.batch.config.BatchDatabaseSettingsLoader; +import org.sonar.core.PicoUtils; import org.sonar.core.i18n.GwtI18n; import org.sonar.core.i18n.I18nManager; import org.sonar.core.i18n.RuleI18nManager; @@ -99,14 +99,14 @@ public final class Platform { startDatabaseConnectors(servletContext); connected = true; - } catch (Exception e) { - LoggerFactory.getLogger(getClass()).error("Can not start Sonar", e); + } catch (RuntimeException e) { + PicoUtils.handleStartupException(e, LoggerFactory.getLogger(getClass())); } } } public void start() { - if (!started && getDatabaseStatus()== DatabaseVersion.Status.UP_TO_DATE) { + if (!started && getDatabaseStatus() == DatabaseVersion.Status.UP_TO_DATE) { try { TimeProfiler profiler = new TimeProfiler().start("Start components"); startCoreComponents(); @@ -114,10 +114,9 @@ public final class Platform { executeStartupTasks(); started = true; profiler.stop(); - } catch (Exception e) { + } catch (RuntimeException e) { // full stacktrace is lost by jruby. It must be logged now. - LoggerFactory.getLogger(getClass()).error("Fail to start server", e); - throw new IllegalStateException("Fail to start server", e); + PicoUtils.handleStartupException(e, LoggerFactory.getLogger(getClass())); } } } |