SonarQube and TeamCity

Recently I attended a Sitecore Usergroup in London, with a talk about Continuous Integration by Andrew Thompson. Among other things, he was talking about SonarQube and how he implemented that in combination with TeamCity. I decided to try my hand on implementing it as well, but found the documentation (or findability of the documentation, more accurately) lacking.

Here are my finds:
I started with installing a local copy of it, with the integrated database. To do this I could simply follow the steps documented in the ‘Get Started in Two Minutes‘ guide.

As that was so easy I figured I’d implement this on our TeamCity server right away, but that was when things got a little more unclear. I tried following the installation guide as much as I could, but initially without the first step – Installing the Database, as I wanted to start off simple. Initially I’d install it with the embedded database (which would of course be a big no-no going forward, so it would have to change later on). Now, I hadn’t had any experience with anything like this before, so I wasn’t sure about the POM file or the properties file, and what I could do with them. A little reading up here told me it was a Project Object Model file, which as the documentation on POMs says: ‘It is a one-stop-shop for all things concerning the project’. Sample pom files for various languages can be found here. I used the sample C# file. A sample sonar.properties file can be found in the same project.

After I created my POM file and properties file I installed the SonarQube server on my TeamCity server. I installed this as a service using the “InstallNTService.bat” file and started the service by using the “StartNTService.bat” file. At the time, I wasn’t an administrator on the server, so I couldn’t initially, but after I had my access rights to the server changed I was able to execute both bat files. My first issue showed up here: I received an error about not being able to start the server because of the language (C#) plugins missing. This is also something the documentation addresses. After installing the C# plugins (which consists of downloading them and copying them into the <sonarfolder>\extensions\plugins folder) I tried running it again, but still no dice, this time I had an error about not being able to locate Java (although I can’t quite remember what the error was). The solution to this was fairly simple, add Java to the PATH environment variable.
This time I got the Sonar server started through the service.

Next step: I had to make sure that my code analysis would be executed from TeamCity, which as specified in the documentation consists of 4 steps:

  1. Make sure the ‘fail build if: at least one test failed’ is unchecked (this can be found in the Build Failure Conditions step in TeamCity).
  2. In the configuration for the Build Step select the runner type Maven with the goals ‘clean install sonar:sonar’.
    As additional Maven command line parameters set ‘-Dmaven.test.failure.ignore=true’
  3. Create a build trigger (I’ve set mine to a daily build)
  4. In the Build Parameters, in the Environment Variables, add a variable called MAVEN_OPTS and set the value to ‘-Xmx512m’.

From TeamCity I now started the project – and it failed. I changed the goal in TeamCity from: Clean install sonar:sonar To: Clean install sonar:sonar –X Which adds extended logging. The issue I was having was that it was using the wrong language (Java) even though I specified sonar.language=cs in my properties file. Adding <sonar.language>cs</sonar.language> to the POM file resolved this. For some reason, it looks like my environment is completely skipping the properties file, which I am currently looking into (although I don’t have too much time to spend on this as it’s already working through the POM file).

Now to remove the database and use a SQL database instead. I found this extremely helpful article to set up Sonar which told me I had to create a new database (I called it simply “sonarqube”) with the collate option SQL_Latin1_General_CP1_CS_AS. The article also gives a seperate link to settings you need to change to enable using a SQL database with SonarQube rather than the default embedded database.

In short, it consists of the following changes:

  • Create a new database (with collate option SQL_Latin1_General_CP1_CS_AS)
  • Set sonar.jdbc.username to the user you want to use
  • Set sonar.jdbc.password to the password of the selected user
  • Change the sonar.jdbc.url to Jdbc:jtds:sqlserver://<database server>;databaseName=database;selectMethod=cursor;
  • Change the sonar.jdbc.driverClassName to com.microsoft.sqlserver.jdbc.SQLServerDriver (this did not work for me – we’ll get to that in a second)
  • Set sonar.jdbc.validationQuery: select 1 (sonar.jdbc.validationQuery wasn’t in my properties file at all, so I had to add this. As I understand it its an optional parameter)
  • Set sonar.jdbc.dialect=mssql (which also wasn’t in my properties file, so added that too)

More information of course is available in the article itself.

After changing the properties to what’s specified in the previous link I was getting errors.
Initially because I didn’t have the correct database access rights for my sonar user, but even after I gave the user dbo access I was getting nowhere starting http://localhost:9000/ – something that was working before I changed databases. My logfiles (located in <sonarfolder>\logs) gave me an error with a huge stack trace, starting with:
Cannot connect to database. Please check connectivity and settings (see the properties prefixed by ‘sonar.jdbc.’). org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class ‘com.microsoft.sqlserver.jdbc.SQLServerDriver’
That did give me a hint of course, and I changed the sonar.jdbc.driverClassName setting to net.sourceforge.jtds.jdbc.Driver (which was the default under SQL Server to begin with). If there’s no driver in <sonarfolder>\extensions\jdbc-driver\mssql it can be downloaded here. Be aware that there can be only one JAR file in that folder.
However, after that it still gave me an error:
INFO | jvm 1 | 2013/08/12 12:58:24 | java.sql.SQLException: No suitable driver
I wasn’t sure how to fix that, so I contacted Andrew to see if he could help out. He kindly agreed to help with my issues: I had my sonar.jdbc.url set to
jdbc:sqlserver://servername;databaseName=sonarqube;selectMethod=cursor;
but it needs to be
jdbc:jtds:sqlserver://servername;databaseName=sonarqube;selectMethod=cursor;
Next thing I encountered was the error
Fail to connect to database: Cannot create PoolableConnectionFactory (Connection is broken: “java.net.ConnectException: Connection refused: connect: localhost
I wasn’t using anything even remotely resembling localhost, so that confused me. Andrew to the rescue again, he was kind enough to send me over one of his POM files.
The difference: In the <properties> node he had the following:
<sonar.jdbc.url>jdbc:jtds:sqlserver://servername;databaseName=sonarqube;SelectMethod=Cursor;</sonar.jdbc.url>
<sonar.jdbc.driver>net.sourceforge.jtds.jdbc.Driver</sonar.jdbc.driver>
<sonar.jdbc.username>username</sonar.jdbc.username>
<sonar.jdbc.password>password</sonar.jdbc.password>
I initially had this in the .properties file, but SonarQube seems to be ignoring that file completely for some reason.

After I added this to my POM file it worked successfully and I could start improving the code.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s