aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2013-08-16 17:46:06 +0200
committerSimon Brandhof <simon.brandhof@gmail.com>2013-08-16 17:46:06 +0200
commit3125bcc453e3973298b7cf417b9ea8a158ba3b8a (patch)
treeb0a5838b76870f46469310aff5ab5138d174eb72
parent906c2b413615c37ead1371bb1422be4c733747fd (diff)
downloadsonarqube-3125bcc453e3973298b7cf417b9ea8a158ba3b8a.tar.gz
sonarqube-3125bcc453e3973298b7cf417b9ea8a158ba3b8a.zip
SONAR-4547 improve support of MessageException
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileSensorTest.java5
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java4
-rw-r--r--sonar-maven-plugin/src/main/java/org/sonar/maven/ExceptionHandling.java39
-rw-r--r--sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java42
-rw-r--r--sonar-maven-plugin/src/test/java/org/sonar/maven/ExceptionHandlingTest.java75
-rw-r--r--sonar-maven-plugin/src/test/java/org/sonar/runner/impl/RunnerException.java26
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/MessageException.java26
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/MessageExceptionTest.java23
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java2
10 files changed, 187 insertions, 63 deletions
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileSensorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileSensorTest.java
index 24fbaa07b45..cce7bab1087 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileSensorTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileSensorTest.java
@@ -20,14 +20,15 @@
package org.sonar.plugins.core.sensors;
import org.junit.Test;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.*;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.test.IsMeasure;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.*;
+
public class ProfileSensorTest {
@Test
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java
index 26f0f425015..6fe7394e040 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java
@@ -59,21 +59,21 @@ public class DatabaseCompatibility implements BatchComponent {
message.append(" / *****)\n\t- Server side: check the configuration at ");
message.append(server.getURL());
message.append("/system\n");
- throw new MessageException(message.toString());
+ throw MessageException.of(message.toString());
}
}
private void checkDatabaseStatus() {
DatabaseVersion.Status status = version.getStatus();
if (status == DatabaseVersion.Status.REQUIRES_DOWNGRADE) {
- throw new MessageException("Database relates to a more recent version of SonarQube. Please check your settings (JDBC settings, version of Maven plugin)");
+ throw MessageException.of("Database relates to a more recent version of SonarQube. Please check your settings (JDBC settings, version of Maven plugin)");
}
if (status == DatabaseVersion.Status.REQUIRES_UPGRADE) {
- throw new MessageException("Database must be upgraded. Please browse " + server.getURL() + "/setup");
+ throw MessageException.of("Database must be upgraded. Please browse " + server.getURL() + "/setup");
}
if (status != DatabaseVersion.Status.UP_TO_DATE) {
// Support other future values
- throw new MessageException("Unknown database status: " + status);
+ throw MessageException.of("Unknown database status: " + status);
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java
index 7d77355ef11..539fc1e4529 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java
@@ -27,6 +27,7 @@ import org.sonar.api.batch.DecoratorContext;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
+import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.DecoratorsSelector;
import org.sonar.batch.DefaultDecoratorContext;
@@ -80,6 +81,9 @@ public class DecoratorsExecutor implements BatchComponent {
decorator.decorate(resource, context);
eventBus.fireEvent(new DecoratorExecutionEvent(decorator, false));
+ } catch (MessageException e) {
+ throw e;
+
} catch (Exception e) {
// SONAR-2278 the resource should not be lost in exception stacktrace.
throw new SonarException("Fail to decorate '" + resource + "'", e);
diff --git a/sonar-maven-plugin/src/main/java/org/sonar/maven/ExceptionHandling.java b/sonar-maven-plugin/src/main/java/org/sonar/maven/ExceptionHandling.java
new file mode 100644
index 00000000000..2fcd44e55e2
--- /dev/null
+++ b/sonar-maven-plugin/src/main/java/org/sonar/maven/ExceptionHandling.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.maven;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+
+class ExceptionHandling {
+
+ static RuntimeException handle(Exception e, Log log) throws MojoExecutionException {
+ Throwable source = e;
+ if (e.getClass().getName().equals("org.sonar.runner.impl.RunnerException") && e.getCause() != null) {
+ source = e.getCause();
+ }
+ log.error(source.getMessage());
+ throw new MojoExecutionException(source.getMessage(), source);
+ }
+
+ static RuntimeException handle(String message, Log log) throws MojoExecutionException {
+ return handle(new MojoExecutionException(message), log);
+ }
+}
diff --git a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java
index 14213720c23..d62389c6970 100644
--- a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java
+++ b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java
@@ -29,7 +29,6 @@ import org.apache.maven.execution.RuntimeInformation;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
@@ -127,23 +126,25 @@ public final class SonarMojo extends AbstractMojo {
*/
RuntimeInformation runtimeInformation;
- public void execute() throws MojoExecutionException, MojoFailureException {
+ @Override
+ public void execute() throws MojoExecutionException {
ArtifactVersion mavenVersion = getMavenVersion();
if (mavenVersion.getMajorVersion() == 2 && mavenVersion.getMinorVersion() < 2) {
- throw new MojoExecutionException("Please use at least Maven 2.2.x to perform SonarQube analysis (current version is " + mavenVersion.toString() + ")");
+ ExceptionHandling.handle("Please use at least Maven 2.2.x to perform SonarQube analysis (current version is " + mavenVersion.toString() + ")", getLog());
}
- EmbeddedRunner runner = EmbeddedRunner.create()
+ try {
+ EmbeddedRunner runner = EmbeddedRunner.create()
.setApp("Maven", mavenVersion.toString())
.addProperties(session.getExecutionProperties())
.addProperties(project.getModel().getProperties())
// Add user properties (ie command line arguments -Dsonar.xxx=yyyy) in last position to override all other
.addProperties(session.getUserProperties());
- String encoding = getSourceEncoding(project);
- if (encoding != null) {
- runner.setProperty(ScanProperties.PROJECT_SOURCE_ENCODING, encoding);
- }
- runner
+ String encoding = getSourceEncoding(project);
+ if (encoding != null) {
+ runner.setProperty(ScanProperties.PROJECT_SOURCE_ENCODING, encoding);
+ }
+ runner
.setProperty(ScanProperties.PROJECT_KEY, getSonarKey(project))
.setProperty(RunnerProperties.WORK_DIR, getSonarWorkDir(project).getAbsolutePath())
.setProperty(ScanProperties.PROJECT_BASEDIR, project.getBasedir().getAbsolutePath())
@@ -151,25 +152,28 @@ public final class SonarMojo extends AbstractMojo {
.setProperty(ScanProperties.PROJECT_NAME, toString(project.getName()))
.setProperty(ScanProperties.PROJECT_DESCRIPTION, toString(project.getDescription()))
.setProperty(ScanProperties.PROJECT_SOURCE_DIRS, ".");
- // Exclude log implementation to not conflict with Maven 3.1 logging impl
- runner.mask("org.slf4j.LoggerFactory")
+ // Exclude log implementation to not conflict with Maven 3.1 logging impl
+ runner.mask("org.slf4j.LoggerFactory")
// Include slf4j Logger that is exposed by some Sonar components
.unmask("org.slf4j.Logger")
.unmask("org.slf4j.ILoggerFactory")
- // Exclude other slf4j classes
- // .unmask("org.slf4j.impl.")
+ // Exclude other slf4j classes
+ // .unmask("org.slf4j.impl.")
.mask("org.slf4j.")
- // Exclude logback
+ // Exclude logback
.mask("ch.qos.logback.")
.mask("org.sonar.")
- // Include everything else
+ // Include everything else
.unmask("");
- runner.addExtensions(session, getLog(), lifecycleExecutor, artifactFactory, localRepository, artifactMetadataSource, artifactCollector,
+ runner.addExtensions(session, getLog(), lifecycleExecutor, artifactFactory, localRepository, artifactMetadataSource, artifactCollector,
dependencyTreeBuilder, projectBuilder);
- if (getLog().isDebugEnabled()) {
- runner.setProperty("sonar.verbose", "true");
+ if (getLog().isDebugEnabled()) {
+ runner.setProperty("sonar.verbose", "true");
+ }
+ runner.execute();
+ } catch (Exception e) {
+ throw ExceptionHandling.handle(e, getLog());
}
- runner.execute();
}
private ArtifactVersion getMavenVersion() {
diff --git a/sonar-maven-plugin/src/test/java/org/sonar/maven/ExceptionHandlingTest.java b/sonar-maven-plugin/src/test/java/org/sonar/maven/ExceptionHandlingTest.java
new file mode 100644
index 00000000000..59d579f33d5
--- /dev/null
+++ b/sonar-maven-plugin/src/test/java/org/sonar/maven/ExceptionHandlingTest.java
@@ -0,0 +1,75 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.maven;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.junit.Test;
+import org.sonar.runner.impl.RunnerException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class ExceptionHandlingTest {
+
+ private static final String MESSAGE = "the error message";
+
+ @Test
+ public void should_log_message_and_throw_exception() throws Exception {
+ Log log = mock(Log.class);
+ try {
+ ExceptionHandling.handle(MESSAGE, log);
+ fail();
+ } catch (MojoExecutionException e) {
+ assertThat(e.getMessage()).isEqualTo(MESSAGE);
+ verify(log).error(MESSAGE);
+ }
+ }
+
+ @Test
+ public void should_log_message_and_rethrow_exception() throws Exception {
+ Log log = mock(Log.class);
+ IllegalStateException cause = new IllegalStateException(MESSAGE);
+ try {
+ ExceptionHandling.handle(cause, log);
+ fail();
+ } catch (MojoExecutionException e) {
+ assertThat(e.getMessage()).isEqualTo(MESSAGE);
+ assertThat(e.getCause()).isSameAs(cause);
+ verify(log).error(MESSAGE);
+ }
+ }
+
+ @Test
+ public void should_hide_sonar_runner_stacktrace() throws Exception {
+ Log log = mock(Log.class);
+ IllegalStateException cause = new IllegalStateException(MESSAGE);
+ try {
+ ExceptionHandling.handle(new RunnerException(cause), log);
+ fail();
+ } catch (MojoExecutionException e) {
+ assertThat(e.getMessage()).isEqualTo(MESSAGE);
+ assertThat(e.getCause()).isSameAs(cause);
+ verify(log).error(MESSAGE);
+ }
+ }
+}
diff --git a/sonar-maven-plugin/src/test/java/org/sonar/runner/impl/RunnerException.java b/sonar-maven-plugin/src/test/java/org/sonar/runner/impl/RunnerException.java
new file mode 100644
index 00000000000..aff129c5355
--- /dev/null
+++ b/sonar-maven-plugin/src/test/java/org/sonar/runner/impl/RunnerException.java
@@ -0,0 +1,26 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.runner.impl;
+
+public class RunnerException extends RuntimeException {
+ public RunnerException(Throwable throwable) {
+ super(throwable);
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/MessageException.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/MessageException.java
index 25290dac9b2..fc41e59c26f 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/MessageException.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/MessageException.java
@@ -20,31 +20,21 @@
package org.sonar.api.utils;
/**
- * Runtime exception for "functional" errors. It aims to be displayed to end-users, without any technical information
- * like stack traces.
+ * Runtime exception for "functional" error. It aims to be displayed to end-users, without any technical information
+ * like stack traces. It requires sonar-runner 2.4. Previous versions log stack trace.
+ * <p/>
+ * Note that by design Maven still logs the stack trace when the option -e is set.
*
* @since 4.0
*/
public class MessageException extends RuntimeException {
- public MessageException(String s) {
- super(s);
+ private MessageException(String message) {
+ super(message);
}
- /**
- * Does not fill in the stack trace
- *
- * @see java.lang.Throwable#fillInStackTrace()
- */
- @Override
- public synchronized Throwable fillInStackTrace() {
- return this;
+ public static MessageException of(String message) {
+ return new MessageException(message);
}
- @Override
- public String toString() {
- return getMessage();
- }
-
-
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/MessageExceptionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/MessageExceptionTest.java
index 0b734416e94..77daa814d37 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/MessageExceptionTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/MessageExceptionTest.java
@@ -21,30 +21,15 @@ package org.sonar.api.utils;
import org.junit.Test;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
import static org.fest.assertions.Assertions.assertThat;
public class MessageExceptionTest {
- /**
- * The exception should log only the message, without the "org.sonar.api.utils.MessageException" prefix
- * and stack traces
- */
@Test
- public void should_not_print_stacktrace() throws Exception {
+ public void should_create_exception() throws Exception {
String message = "the message";
- try {
- throw new MessageException(message);
-
- } catch (MessageException e) {
- StringWriter writer = new StringWriter();
- e.printStackTrace(new PrintWriter(writer));
-
- assertThat(e.getStackTrace()).isEmpty();
- assertThat(e.getMessage()).isEqualTo(message);
- assertThat(writer.toString()).isEqualTo(message + System.getProperty("line.separator"));
- }
+ MessageException exception = MessageException.of(message);
+ assertThat(exception.getMessage()).isEqualTo(message);
+ assertThat(exception).isInstanceOf(RuntimeException.class);
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java b/sonar-server/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java
index a8fb1a922a4..12043a4fdd9 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java
@@ -35,7 +35,7 @@ public class DatabaseServerCompatibility implements ServerComponent {
public void start() {
DatabaseVersion.Status status = version.getStatus();
if (status== DatabaseVersion.Status.REQUIRES_DOWNGRADE) {
- throw new MessageException("Database relates to a more recent version of sonar. Please check your settings.");
+ throw MessageException.of("Database relates to a more recent version of sonar. Please check your settings.");
}
if (status== DatabaseVersion.Status.REQUIRES_UPGRADE) {
LoggerFactory.getLogger(DatabaseServerCompatibility.class).info("Database must be upgraded. Please browse /setup");