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
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);
}
}
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;
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);
--- /dev/null
+/*
+ * 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);
+ }
+}
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;
*/
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())
.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() {
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
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();
- }
-
-
}
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);
}
}
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");