Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Info
iconfalse
titleTable of Contents
Table of Contents

General Questions

What is the difference between the Sonar .NET Plugins (up to version 0.6) and the Sonar C# Plugins Ecosystem (from version 1.0)?

Historically, the support for the C# language was created under the ".NET Plugins" name, from version 0.1 to latest 0.6 released in June 2011.
In the mean time, a complete rewrite of those plugins started in late 2010 in order to make C# a first-class language in Sonar. This not only involved upgrading the plugins to the latest APIs and Sonar development best-practices, but also making evolutions on the core of the Sonar platform itself to support new needs that the Java world had not brought before.
The set of plugins was rebranded "C# Plugins Ecosystem" to highlight the enhanced support of the C# language (C# being just one of several languages running on top of the .NET platform).

The main differences between those 2 sets of Sonar plugins are:

  • Home-made C# parser: no need to install SourceMonitor anymore, all the metrics are computed by the brand-new Sonar C# Core plugin. This opens lots of possibilities for the future, like being able to create our own C# rules.
  • Better support of copy-paste detection, based on the new C# parser
  • Maven is no more required for execution: assuming that you're solution has been compiled, you can run a Sonar analysis just with the Sonar Runner
  • Java 6 is no more required for execution: the plugins run fine on a Java 5 VM
  • Native support of Sonar way to handle multi-module: a .NET solution that contains C# projects will be considered like a standard root project with modules in Sonar. Each tool such as FxCop, StyleCop or Mono Gendarme will be run on each of these Visual Studio projects. With the dotnet plugin version 0.6, except for Gendarme, tools were launched only once for a whole Visual Studio solution.

Unlike the former dotnet plugins, the Sonar C# plugins do not provide features such as compilation or packaging. These plugins are focused on their job : code quality analysis. That being said for compilation/packaging. You can still use whatever solution best feet your needs such as MsBuild scripts, Nant scripts or the maven-dotnet-plugin if you are familiar with maven.

Tip
titleTo remember

The C# Plugins Ecosystem is not just an evolution of the .NET plugins, it is a complete rewrite and thus introduces many changes. If you were a .NET plugins user before, we advice you to read the notes below about the migration process.

How should I migrate from the .NET Plugins 0.6 to the new C# Plugins Ecosystem 1.0, and what will change?

We tried to ensure backward compatibility at configuration level as much as possible, so the migration process should be pretty simple: remove the .NET plugins and add the new C# ones.
If you where using the dotnet plugins, your maven configuration files do not need to change at all and can be reused with the new C# plugin. There is just a tiny exception to the previous sentence, if you use NCover for test coverage. See below for details...

Below a list of things to consider when migrating :

  1. Gallio is not embedded anymore. Dotnet plugins version 0.6 comes with an embedded version of Gallio. This is not the case of the C# Gallio plugin which needs Gallio installed on the boxes where the analysis will be performed.
  2. NCover is not activated the same way using property "useNCover". Instead you need to set property "sonar.gallio.coverage.tool" to "NCover".

So far we have seen only those two points. We'll enhance this section as we get feedback from users.

Note
titleWhat will changes once the migration is done?

Size & complexity metrics are now computed by the C# Core Plugin, so they will definitely change (results will better reflect the reality, hopefully). As a consequence, this will also have impacts on some other metrics, like the rule compliance for instance.

Do I really need Java in order to analyse my C# projects ?

Actually you do not !
The analysis can be triggered either by the Sonar Runner or by maven. Both are Java programs so what is the trick? The Sonar Runner works fine with IKVM. IKVM is a very nice open source project which implements java in .net. If you want to try it with the Sonar Runner, you just need to edit the script sonar-runner.bat and replace the call to java by a call to IKVM:

Code Block
rem "%JAVA_HOME%\bin\java.exe" %SONAR_RUNNER_OPTS% -classpath "%SONAR_RUNNER_HOME%\lib\sonar-runner.jar";"%SONAR_RUNNER_HOME%\lib\sonar-batch-bootstrapper.jar" "-Drunner.home=%SONAR_RUNNER_HOME%" "-Dproject.home=%PROJECT_HOME%" org.sonar.runner.Main %*
 
PATH_TO_IKVM\ikvm.exe %SONAR_RUNNER_OPTS% -classpath "%SONAR_RUNNER_HOME%\lib\sonar-runner.jar";"%SONAR_RUNNER_HOME%\lib\sonar-batch-bootstrapper.jar" "-Drunner.home=%SONAR_RUNNER_HOME%" "-Dproject.home=%PROJECT_HOME%" org.sonar.runner.Main %*

In place of java, a .net process will be used. IKVM will recompiled on the fly the java jars used for the analysis to .net dll files. The recompilation will slow down significantly the analysis. IKVM could be used to transform jar files to dll files prior to any execution (using ikvmc). The problem is that the sonar runner downloads plugins jar files at the beginning of the analysis from the target sonar server instance. Hence we cannot pre compiled all the jars files needed to run an analysis without changing the way the runner works. 
Right now it is not very useful to use IKVM with the sonar runner. However, this looks very promising for a future Visual Studio integration (wink)

How can I exclude a project from the analysis of a .NET solution?

You can do so using the standard "sonar.skippedModules" property (see Analysis Parameters page for Sonar properties): it is a comma-separated list of project names. The names that you must use here are the identifiers that you can find in the .SLN file: the identifier is the first string you can find right after the equals sign on a project definition. 

For instance, on the following SLN file excerpt, you would use "FooProject":

Code Block
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "FooProject", "FooProject", "{59BECB8B-A7E3-4823-9CE6-584D0D1755EE}"

Sonar C# Parser

What are the current limitations?

Currently, the SonarSource C# parser has the following limitations:

Rules

How can I use FxCop with Visual Studio Static Analysis rules in sonar?

Check out this page, where everything is explained.

Tests and code coverage

How can I run Gallio and PartCover on a 64-bits Windows?

Gallio and PartCover work perfectly out-of-the-box on x86 Windows, but not on 64-bits versions of this OS. To make them work correctly, here's what you have to do:

  1. Download the latest Gallio x64 installer (http://www.gallio.org/Downloads.aspx) and install it in a folder not under "Program Files"
  2. Download the latest PartCover installer (https://github.com/sawilde/partcover.net4, click on Downloads) and install it in a folder not under "Program Files"
  3. Run "corflags.exe" on Gallio and PartCover executables:

    Code Block
    ## go into PartCover folder
    corflags /32bit+ /force PartCover.exe
    corflags /32bit+ /force PartCover.Browser.exe
    ## go into Gallio bin folder
    corflags /32bit+ /force Gallio.Echo.exe
    

(Source: http://www.planetgeek.ch/2009/10/15/get-partcover-running-on-x64-windows/)

How can I run integration tests ?

Note

Available since version 1.3 of the C# plugins

Integration testing is activated using property sonar.gallio.it.mode :

Code Block
sonar.gallio.it.mode=active

Integration tests must be part of the analysed solution. They can either be located in dedicated projects or located in regular test projects, next to unit tests.
If there are located in dedicated projects, theses projects need to be specified using property sonar.dotnet.visualstudio.itProjectPattern. Below an example :

Code Block
sonar.dotnet.visualstudio.itProjectPattern=*.IntegTest

If integration tests are next to unit tests, in the same projects, you need to specify to sonar which ones are unit tests and which ones are integration tests. Gallio filters comes to the rescue : 

Code Block
sonar.gallio.filter=CategoryName:unit
sonar.gallio.it.filter=CategoryName:selenium

With the preceding configuration fragment, all test cases annotated "unit" (i.e. [Category("unit")]) are considered to be unit test cases whereas test cases annotated "selenium" (i.e. [Category("selenium")]) are considered to be integration test cases.

Compatibility with other plugins

SCM Activity plugin

The C# Plugins Ecosystem is compatible with the SCM Activity plugin, provided that you have specified the "sonar.scm.url" property in your POM or "sonar-project.properties" file. For instance:

Code Block
sonar.scm.url=scm:svn:http://my.svn.server/my-repo/trunk/my-project

Other plugins

Those plugins have been reported as compatible with the C# Plugins Ecosystem:

  • Build stability
  • Timeline
  • Radiator
  • Sqale
  • Views

Integration of Sonar with Other Environments

How can I integrate Sonar in my existing TFS Build environment processes?

Most people want to add Sonar as an additional step in existing processes, which usually brings a lot of troubles because those processes manipulate the generated artifacts (assemblies) - whereas Sonar C# Plugins rely best on information found in the source files (mostly CSPROJ config files).

Generally speaking, it's best / easier to set up a separate "continuous inspection" process that just:

  1. compiles the solution
  2. runs a Sonar analysis

, in order to keep the Sonar-related configuration as simple as possible.

...

Source Tree Directory

The source directory tree has to match the package declarations.

For example, the following class:

Code Block
titleMyClass.java
linenumberstrue
languagejava
package com.mycompany.mypackage;
...

should be located in the following directory: [myBaseDir]/com/mycompany/mypackage/MyClass.java.

Otherwise you would get such an error while running your analysis:

Code Block
titleLog
languagenone
Exception in thread "main" org.sonar.batch.bootstrapper.BootstrapException: org.sonar.squid.api.AnalysisException: Got an exception - org.so
nar.squid.api.AnalysisException: The source directory does not correspond to the package declaration com.mycompany.mypackage, file : ..\src\MyClass.java
...

Maven analysis

What is the difference between org.codehaus.mojo:sonar-maven-plugin and org.codehaus.sonar:sonar-maven-plugin?

Here is the rational: Sonar needs a Maven plugin to perform analysis of your project. This plugin is part of Sonar project so the name of this plugin is org.codehaus.sonar:sonar-maven-plugin because codehaus is hosting the project. Each time there is a new version of Sonar, there is a new version of the Sonar plugin. For a given version of the Sonar server, you MUST run the same version of the Sonar Maven plugin. It means that you would have to run

Code Block
mvn org.codehaus.sonar:sonar-maven-plugin:2.5:sonar

if you have installed Sonar 2.5.
As this is very annoying to type, you could add the groupId in your settings.xml. This way you could type:

Code Block
mvn sonar:sonar

BUT in this case the latest version of the Sonar plugin would be taken. As soon as Sonar 2.6 would be released, Maven would automatically use the plugin in version 2.6. If you don't plan to upgrade your Sonar server, it will fail. The answer to this problem is already well-known: define all versions of your plugins in the pom. So you would add:

Code Block
<plugin>
    <groupId>org.codehaus.sonar</groupId>
    <artifactId>sonar-maven-plugin</artifactId>
    <version>2.5</version>
</plugin>

in all pom (or in corporate pom). And you would have to update your projects each time you are updating sonar server. Very annoying but that's not all.
What if you have an integration/acceptance/pre-production instance of Sonar in version 2.5, and a production version in version 2.4? You can't analyse the same project with the two instances because you have fixed the version of the sonar plugin to version 2.5 in the pom. You may finally make it works with external properties or any other ugly hack.

The solution proposed by Sonar team is to use a bootstrap plugin. This plugin:

  • is hosted in org.codehaus.mojo groupId in order to save the settings.xml configuration
  • is supposed to be very stable (ie do not change for each Sonar server release)

When you run

Code Block
mvn sonar:sonar

Maven understands:

Code Block
mvn org.codehaus.mojo:sonar-maven-plugin:LATEST:sonar

. The bootstrap plugin will query Sonar server to find its version, then fork a new build to run the normal plugin with

Code Block
mvn org.codehaus.sonar:sonar:maven-plugin:XX:sonar

where XX is the version previously returned by the server. This way you can analyse the same project with different versions of Sonar and still running the same command line (except Sonar hostname of course) and without having to modify the pom.

Most of the time you need latest version of the boostrap plugin, so no need to fix its version in your pom, except if you want to test a particular version (an old one or a SNAPSHOT for example).

Maven mirrors : the maven plugin fails to resolve org.codehaus.sonar.runtime.* dependencies

This issue occurs when using a Sonar version prior to 2.2. To fix it, it's recommended to upgrade Sonar and the maven plugin to version 1.0-beta-2 (for Maven 2 projects) or 2.0-beta-2 (for Maven 3 projects).

Sonar embeds its own maven repository which is used by the Sonar maven plugin to download all Sonar extensions like pmd, checkstyle, findbugs, etc. If you get this error, it's certainly because your Maven configuration prevents Sonar from accessing its own Maven repository. Your maven settings.xml file must certainly contain a section called <mirror> which should look like this :

Code Block
<mirror>
    <id>nexus</id>
    <mirrorOf>*</mirrorOf>
    <url>http://nexus/</url>
    <name>Central maven repository</name>
</mirror>

According to this section, Maven redirects all calls to the repository called 'nexus', so Sonar maven repository is never touched and Sonar maven plugin fails to resolve org.codehaus.sonar.runtime.* dependencies. Two solutions to solve this issue:

  • If you have Maven version 2.0.9 or higher, just change the value of <mirrorOf> by

    Code Block
    <mirrorOf>*,!sonar</mirrorOf>
  • Or configure your central maven repository (eg. Nexus, Archiva or Artifactory) to use the Sonar internal repository (http://sonar:9000/deploy/maven).
Error resolving version for 'org.codehaus.mojo:sonar-maven-plugin': Plugin requires Maven version 3.0

This error means that you're using Maven 2.0.10 or Maven 2.0.11. Due to SONAR-1994, you must add the following lines to the pom.xml file :

Code Block
<build>
  <pluginManagement>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>sonar-maven-plugin</artifactId>
        <version>1.0</version>
      </plugin>
    </plugins>
  </pluginManagement>
</build>
Cobertura exception on Linux System while accessing the cobertura.ser file

When reading the cobertura.ser file, the Cobertura Maven plugin tries to get a lock on that file. This locking mechanism generates an exception on Linux Systems SONAR-172.

The current workaround is to add the following lines to the pom.xml file (thanks to Wouter de Vaal) :

Code Block
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <version>2.4.3</version>
   <configuration>
      <systemProperties>
         <property>
            <name>cobertura.use.java.nio</name>
            <value>false</value>
         </property>
      </systemProperties>
   </configuration>
</plugin>
The plugin 'org.apache.maven.plugins:maven-sonar-plugin' does not exist or no valid version could be found

If you get this error message after launching the maven command line "mvn sonar:sonar" add the "-U" parameter to the command line. Maven will then update its local repository with the latest version of the Sonar Maven plugin.

If adding the "-U" parameter doesn't fix your issue, you've certainly encountered Maven bug MNG-4001. The only known workaround is to delete the org\codehaus\mojo directory in your local Maven repository. Of course, if your local Maven repository is synchronized with a repository manager like Nexus, this operation must be also done on the repository manager side.

Maven fails with an OutOfMemoryError

Increase the maven available memory by setting the environment variable :

Code Block
MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=256m"
Maven fails with a SecurityException

The message of the root exception is

Code Block
class "org.sonar.commons.database.SchemaInfo$$EnhancerByCGLIB$$15d095d4"'s signer information does not match
signer information of other classes in the same package

The CGLIB library available in your Maven repository is certainly signed which is not the case on IBIBLIO repository. Perhaps you or your Maven administrator have signed this jar to include it into a Java Web Start application. Unfortunately signing CGLIB jar file breaks Hibernate's use of CGLIB, as it generates proxy classes in the same package (org.sonar.commons.database.* for our context) as the original class. But the original Sonar class is not signed and the new proxy class is, generating a java.lang.SecurityException.

You must also sign Sonar libraries in your Maven repository or used unsigned CGLIB library.

Maven fails with a NoClassDefFoundError

Typically error message looks like :

No Format
java.lang.NoClassDefFoundError: org/apache/commons/configuration/Configuration

Possible explanations of such problem :

  1. Your Maven repository (local or remote) contains corrupted JARs.
  2. You have exceeded limit of open files - see http://markmail.org/message/wvfvafgrga5b6tnd.
Maven fails because of Maven Enforcer violations

You have to add the parameter -Denforcer.skip=true to the Maven command-line.

Failed to resolve stax2-api artifact

The following error occurs when using Maven Archiva 1.1. It must be upgraded to 1.2.1.

Code Block
[INFO] Failed to resolve artifact.

No versions are present in the repository for the artifact with a range [3.0.0,3.1.0)
org.codehaus.woodstox:stax2-api:jar:null
Findbugs fails on timeout

See SONAR-1439. Findbugs fails with the following logs :

Code Block
[java] Timeout: killed the sub-process
...
[Fatal Error] :-1:-1: Premature end of file.

Add the findbugs-maven-plugin to the plugins section of the pom and configure the parameter "timeout".

0% code coverage reported whereas unit tests are correctly executed

This problem occurs when using the Maven Cobertura Plugin and a special configuration of the Maven Surefire Plugin preventing unit tests to be forked. This problem can be solved by removing the line "<forkMode>never</forkMode>" in the Maven configuration file (see SONAR-1445 and MCOBERTURA-70).

My project only builds with JDK1.4

As Sonar can only run with JDK1.5 or higher, some configuration should be added to the pom.xml to indicate that the project requires JDK1.4:

Code Block
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.4</source>
        <target>1.4</target>
    </configuration>
</plugin>