Pair Programming: a few thoughts

I recently read a great article on pair programming by a developer over at Atlassian where he really summed up my views on the topic. I have had really good experiences with pairing and some not so good ones.

What came out of some of the more positive experiences were:

  • I came up to speed on a new system quickly
  • Risks or major design questions were verbalised and dealt with sooner
  • I learnt more efficient ways of coding things
  • I learnt more cool eclipse keyboard shortcuts!
  • My TDD and general development skills rapidly increased

Some of the more difficult experiences:

  • I felt frustrated at the sometimes slow pace
  • Sometimes my pair would dominate the keyboard so it was easy to drift off into la la land
  • When joining an existing team I worried I wasn’t learning enough of the system and if they were sick that day I’d be lost

Some of the paring experiences Ive had I didn’t realise until much later how extremely valuable they really were.

I think in order for pairing to be successful you should:

  • rotate partners often
  • be open to constructive criticism on code improvements
  • voice your opinion/suggestions so you can work a team to develop a solution
  • take breaks every couple of hours to check email/facebook – refresh
  • ensure you get equal keyboard time
  • keep trying! – pairing wont come naturally to everyone but there are a lot of benefits to come out of it and its a chance to really improve as a developer

If your workplace doesn’t see the value in pairing then as stated in the article, I think the next best thing is to make sure you get an extra set of eyes on every line of code committed, whether its using a code review tool or as I did on a former project, have another developer check over your code before each commit.

Advertisements

Sonar and Hudson

I recently found out about Sonar after finding issues with running Cobertura on multi-module maven projects (see nabble post). Sonar looked like it solved this issue and added a whole stack more insight into the code quality of a project.
I got a Sonar demo up and running fine locally and convinced my team it would be a benefical tool for us to use so the next step for me was to install Sonar on our development box and integration it with our CI server, Hudson.
There seems to be two ways you can achieve Sonar and Hudson integration:

  1. Use the Sonar Hudson plugin and run Sonar as an ‘after build’ task
  2. Run mvn sonar:sonar in a within Hudson

I had a lot of issues trying to get the plugin to work so I ended up going with option 2. Below are the steps I took to get it to work.

  1. Firstly you need to download and install Sonar. You can do this buy executing the run script or by building and deploying the war file into an applicaiton server. I had issues with Glassfish so I just opted for running it from the run script and for now, I just stuck with the default Derby database.
  2. Starup Sonar and browse to http://hostname:9000 to make sure it’s up and running.
  3. Edit the maven settings.xml that is located on the same machine as your Hudson server and add in the following
  4. Add in a new repository under your exising one.

    <repository>
              <id>sonar</id>
              <name>Sonar Repository</name>
              <snapshots>
                <updatePolicy>daily</updatePolicy>
                <checksumPolicy>ignore</checksumPolicy>
              </snapshots>
              <url>http://hostname:9000/deploy/maven</url>
            </repository>
    

    Add in a new sonar profile

    <profile>
    <id>sonar</id>
    <activation>
    <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
    <sonar.jdbc.url>
                      jdbc:derby://localhost:1527/sonar;create=true
                    </sonar.jdbc.url>
                    <sonar.jdbc.driver>org.apache.derby.jdbc.ClientDriver</sonar.jdbc.driver>
                    <sonar.jdbc.username>sonar</sonar.jdbc.username>
                    <sonar.jdbc.password>sonar</sonar.jdbc.password>
    <sonar.host.url>http://hostname:9000</sonar.host.url>
    </properties>
    </profile>
    

    update your nexus mirror

        <mirror>
          <id>hsl-repository-mirror</id>
          <mirrorOf>*,!sonar</mirrorOf>
          <url>http://maven-repository:8181</url>
        </mirror>
    
  5. Now you can create a new job in Hudson and run it with the following maven command:
    clean install sonar:sonar

    That’s it! You should be able to browse to your sonar page and see your project there with coverage results. I had my job execute ever day at 11pm rather than on SVN commit.

    It’s worth pointing out that the above mvn command will run the tests twice, firstly during install and secondly during sonar:sonar. Take a look here for more info. In order to speed this up it might be worth adding in the following paramater at the end of the command:

    -Dsonar.dynamicAnalysis=reuseReports

    If you want to generate sonar results even if the build fails add this paramater

    -Dmaven.test.failure.ignore=true

    All together that would be:

    clean install sonar:sonar -Dsonar.dynamicAnalysis=reuseReports -Dmaven.test.failure.ignore=true

If you you are getting out of memory exceptions, consider editing the MAVEN_OPTS under Advanced in your job configuration to have the following value:

-Xmx256m -XX:MaxPermSize=256m

Running JavaFX project on Linux thru Hudson

If you want to get your FX project setup as a Job in Hudson. Simply follow the steps below and victory will be yours!

  • Download the javaFX1.2 SDK installation file for Linux
  • Copy the installation script to the desired locatio
  • Create a new environment variable $JFX_HOME and set it to the base directory of you fx sdk installation
  • Create a simple HelloWorld.fx script and test it’s compiling eg.
  • import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.text.Text;
    import javafx.scene.text.Font;
    
    Stage {
        title: "Application title"
        width: 250
        height: 80
        scene: Scene {
            content: Text {
                font : Font {
                    size : 24
                }
                x: 10, y: 30
                content: "Application content"
            }
        }
    }
    

    Then verify it’s running by executing the javaxc command (much like javac)

  • Add a pom.xml to your project that looks like the one below
  • <build>
    		<sourceDirectory>src</sourceDirectory>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<configuration>
    					<compilerId>javafxc</compilerId>
    					<include>**/*.fx</include>
    					<fork>true</fork> <!-- NOTE: only โ€œforkโ€ mode supported now -->
    				</configuration>
    				<dependencies>
    					<dependency>
    						<groupId>net.sf.m2-javafxc</groupId>
    						<artifactId>plexus-compiler-javafxc</artifactId>
    						<version>0.3</version> 
    					</dependency>
    				</dependencies>
    			</plugin>
    		</plugins>
    	</build>
    
  • Add a new job in Hudson for a maven2 project and kick off a build. All should be well! If you do get an exception like the one below, then verify your $JFX_HOME variable is set correctly. I had to restart Glassfish in order for Hudosn to pick up the new variable.
  • Caused by: java.lang.NullPointerException
    	at java.io.File.<init>(File.java:222)
    	at net.sf.m2javafxc.javafxc.JavafxcCompiler.compile(JavafxcCompiler.java:146)
    	at org.apache.maven.plugin.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:493)
    	... 32 more
    

    Grails Pagination with Multiple Order Clauses – How To

    There is a known bug in grails where you can’t have multiple order by’s when returning a PagedResultList. When talking about the .createCriteria().list() method it seems you can only specify the order by inside the .list() method and not in the builder body itself even if only ordering by one values.

    This is very annoying as I think multiple order by’s would be a common requirement of a lot of apps. Below is my work around to this bug. I’ll investigate providing a patch to fix this in the near future.

    Let’s start by taking a look at three ways you might use to query the database:

    Our domain class looks like this:

    @Entity
    @Table(name = "tbl_book")
    public class Book {
    
    @Id
    @Column(name = "bookId")
    private int id;
    private String author;
    private String title;
    private Date releaseDate;
    
    // getters and setters
    
    1. Dynamic Methods:
      def results = Book.findAllByAuthor("Marsden", [max:10, offset:0, sort:"releaseDate", order:"desc"])

      The above method would return a PagedResultList ordered by releaseDate descending, but what if we want to order by venue as well? We can’t! Moving on…

    2. def results = Book.createCriteria()
               def results = Book.createCriteria().list(
                   max: params.max,
                   offset: params.offset) {
                   and {
                       eq('author', 'Marsden')
                       order('releaseDate', 'desc')
                       order('title', 'asc')
                   }
               }  

      The above thows a runtime sql exception, you can get it to work only by including the order in the .list() function and only if you include just one order statement, further details of the bug here. Sigh…

    3. def results = Book.withCriteria()
              def results = Book.withCriteria() {
                  maxResults(params.max?.toInteger())
                  firstResult(params.offset?.toInteger())
      
                  and {
                      eq('author', 'Marsden')
                      order('releaseDate', 'desc')
                      order('title', 'asc')
                  }
              }
      

      The above looks fine except it doesn’t return an instance of PagedResultList which means we don’t have access to the results.totalCount method which gives us the total number of results needed for pagination in the g:pagination tag in the view. Still no dice…!

    Solution

    Use query method 3, Book.withCriteria() and then create a seperate query to return the total number of results eg:

            def rowCount = Book.createCriteria().get() {
                projections {
                    rowCount()
                }
                and {
                    eq("author", params.author)
                }
            }
    

    rowCount should then be passed to your view so the pagination tag can use it:

                <div class="paginateButtons">
                    <g:paginate total="${rowCount}" />
                </div>
    

    This solution is really ugly. Im not a fan of having to execute the query twice just to get the total count. I really hope this bug is fixed soon, or someone tells me im missing something fundamental ๐Ÿ™‚

    Nabble questions on this here and here.

    Populating a select box in Grails with values from database

    A fairly common requirement is to populate values in a select box/drop down box with values from a database. It’s quick and easy to do in Grails.

    1. Inside your Contorller, create your query in the closure associated with your view. Eg. I’m going to create a new object that contains a list of values from that database and return it to the search.gsp view:
    2. def search = {
        def authors = Book.executeQuery("SELECT distinct b.author FROM Book b")
        [authors : authors]
      }
    3. Inside your search.gsp, add a select box that displays the list of countries:
      <g:select id="authorSelection" name="author" from="${authors}" value="" noSelection="['':'Please Select...']> 
    4. When you are reading the value back out of the form in your controller, simply use:
      params.author
    5. You’re done! Easy peasy.

    EDIT: I recently found an official looking tutorial about how to do selects with grails here.

    Debugging in Grails

    Debugging your Grails app is just like remote debugging a regular java app.
    1. Firstly in eclipse create a remote debugging configuration and click run. The default port is 5005.

    Debug Config

    2. Start up grails in debug mode. Do this by typing the following command:

    grails-debug run-app

    3. That’s it! More info here.

    JasperReports and Maven

    Simply add the dependency and plugin to your pom as follows:

    <build>
    	<plugins>
    		<plugin>
    			<groupId>org.codehaus.mojo</groupId>
    			<artifactId>jasperreports-maven-plugin
    			</artifactId>
    			<configuration>
    				<outputDirectory>target/jasperreports
    				</outputDirectory>
    			</configuration>
    			<executions>
    				<execution>
    					<goals>
    						<goal>compile-reports</goal>
    					</goals>
    				</execution>
    			</executions>
    
    			<dependencies>
    				<!--
    					note this must be repeated here to pick up correct xml validation
    				-->
    				<dependency>
    					<groupId>jasperreports</groupId>
    					<artifactId>jasperreports</artifactId>
    					<version>3.5.3</version>
    				</dependency>
    			</dependencies>
    		</plugin>
    	</plugins>
    </build>
    

    You can then compile the jrxml files using the following command:

    jasperreports:compile-reports