Saturday, April 6, 2013

Javascript Logging

When developing Javascript applications, we often need to do some logging and we usually resort to using console.log, which typically isn't a good thing to have in production code. I've been doing some research into Javascript logging frameworks, and there are quite a few of them.

log4javascript looks to be one of the more promising ones. It is still being actively updated, and the API is pretty straightforward, especially if you've used other logging frameworks like log4j. They even provide a default logger that requires no configuration to get running:

var logger = log4javascript.getDefaultLogger();
logger.debug("this is a debug message");

There are various types of appenders, including one that sends the log message through an ajax call to the server so the log message can be saved on the server.

If you're doing any sort of logging in your Javascript app, this is definitely worth a look.

Tuesday, March 5, 2013

Unstable builds in Jenkins

We use Jenkins for our continuous integration server, and I've never really seen the need for it to have an "unstable" build status. I actually think this build status does more harm than good. I've found that unstable can be treated in one of two ways - either it is treated like a build failure and fixed immediately or it is treated as not important and ignored. Either way, I think it loses its meaning.

It's also a bit unclear as to what "unstable" actually means. Some coverage plugins for example will set the build to unstable if the coverage level falls below a certain threshold. In this case, if coverage is too low, I wouldn't feel comfortable producing a build that is production ready, so I would fail the build. It's also possible to configure Jenkins to mark a build as unstable on test failures, instead of failing the build - I'm not even sure why that option exists.

I believe the build should only have two states - passed or failed. Whenever I start a new Jenkins project, I always configure any of the plugins I'm using to not use the unstable state (configuration varies from plugin to plugin). I've found keeping out the "unstable" state has led to healthier builds overall.

Friday, February 15, 2013

Why I switched to IntelliJ

For the last few years, I have been an Eclipse user. It's free, and for the most part, it worked pretty will with the occasional crash. However, I've found that it performs really poorly when it comes to dynamic languages. The groovy/grails autocomplete is mediocre, but where I really had issues is with Javascript. It got to a point where every time I tried to save a Javascript file, I was getting a NullPointerException.

So I decided to try out IntelliJ Ultimate based on a colleague's recommendation. Overall, I've been happy with the experience. It is very stable (I've only had one crash since I've been using it, and I was running a lot on my system at once). Deploying to Tomcat servers has been a breeze.

It's not without its quirks though. For example, things that just work in Eclipse, such as auto-wrapping long comment lines, don't work in IntelliJ. I've also found that the gradle support is still new and can be buggy at times (especially with auto-synchronizing Intelli's dependencies with the gradle build's dependencies - though I've heard that's in the works).

What I've been most impressed with is the support. Whether on the Jetbrains forums, bug tracker or stack overflow, the IntelliJ support team generally responds very quickly to posts.

Overall, it has been a pleasant experience. If you're fed up with Eclipse, I recommend giving IntelliJ a try.

Wednesday, January 23, 2013

Spring Profiles

Much of my web development over the past few years has been with Grails on the back end, and although Grails is built on Spring, it's still a good idea to keep up on the new Spring features - you never know when they'll come in handy.

I recently found myself creating a pure Spring app and missing a feature that I really like in Grails - environment based configuration. Fortunately, Spring 3.1 introduced the concepts of profiles, which is as simple as using the @Profile annotation.

First, configure an application context using the @Configuration annotation.

@Configuration
public class ProductionApplicationContext {
    public SomeBeanInterface myBean() {
        return new MyProductionImplementationOfSomeBean();
    }
}
@Configuration
public class TestApplicationContext {
    public SomeBeanInterface myBean() {
        return new MyTestImplementationOfSomeBean();
    }
}
Now we can specify which profile the context is associated with by adding the @Profile annotation
@Configuration
@Profile("production")
public class ProductionApplicationContext {
 // bean defs 
}
@Configuration
@Profile("development")
public class TestApplicationContext {
  // bean defs
}
Now when you start your app, provide the spring.profiles.active system property to specify the profile(s) to use. You can also specify the default profile to use in your web.xml file by adding the following block
<context-param>
    <param-name>spring.profiles.default</param-name>
    <param-value>production</param-value>
</context-param>

Monday, October 22, 2012

Using Core Groovy AST Transforms

Have you ever used an Abstract Syntax Tree (AST) transform? If you're using groovy or grails, chances are you have, and maybe you just didn't know it. An AST allows code to be modified at compile time. Groovy provides the capability to write both local (annotation driven) and global (globally applied) AST transforms. They have a nice tutorial http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations.

Even if writing AST transforms is not something you are doing, you can benefit from the numerous built in transforms that groovy provides. Many of these help to eliminate the need for boilerplate code that we've all written before. This post does not aim to list all of them, but rather to provide you an overview of some of them. Check out all implementors of the ASTTransformation from the groovy api (http://groovy.codehaus.org/api/org/codehaus/groovy/transform/ASTTransformation.html to see a full list.

Consider a Money class that looks

class Money {
    int amount
    String type // USD, Euro, etc

    boolean equals(Money other) {
        if ( other == this ) {
            return true
        }
        if ( other instanceof Money ) {
            return amount == other.amount && type == other.type
        }
        return false
    }

    int hashCode() {
        return new Integer(amount).hashCode() + type.hashCode()
    }
}

This is fairly verbose at best, and at worst, it's very error prone. What if I add a new field to the Money class and update the equals but forget to update the hash code (yes, tests should catch this). What if I forget to add the field to equals and hash code all together?

In Java, you might use Apache Commons' EqualsBuilder and HashcodeBuilder's reflection methods. This certainly simplifies your code, but the performance can be pretty bad if these methods are called frequently.

Enter the AST transform.

@EqualsAndHashCode
class Money {
    int amount
    String type // USD, Euro, etc

}

The @EqualsAndHashCode annotation adds the code at compile time, so you don't take the runtime hit, but you get the benefit of not having to write the code yourself.

Some other useful transforms include
@ToString - Adds a toString method
@Bindable - Adds property change support
@Mixin - Mixes in code to classes

As you can see, AST transformations can provide a lot of benefit and reduce the amount of boiler plate code you need to write. If you haven't used them before, I encourage you to at least take a look.

Thursday, October 4, 2012

Build quality in from the start

Have you ever joined a large project in progress only to find that the project is a bit on the messy side? There's no testing, no automated builds and really no quality control. Did you wonder how it got that way? Then you try to correct some of these problems only to realize you're only making a minor dent (better than nothing). But if the project is in that state, it's likely going to be an uphill battle.

Even the largest of projects start small, and it is much easier to build the quality control into the product at the beginning of the project. At the start of a project, use "iteration 0" for setting up the test and automation infrastructure. There are a certain set of tools at a minimum that I prefer to use for projects. 

Version control - this one should be obvious, but I'll include it here anyway. Whether you use a traditional VCS or distributed VCS may vary based on your needs, but use something.

Unit testing framework - again here, hopefully this one is obvious also. I typically use JUnit, but other tools such as spock can be useful. Also included here are any of the other unit testing framework, such as DBUnit or XMLUnit.

Acceptance testing framework - have a look at Selenium/Webdriver coupled with Spock or Cucumber. Cucumber is a little more complex but lets you write business requirements in plain language rather than in code.

Automated build/Dependency Management tools - ant/ivy, maven or gradle. Pick your poison. I like maven because it is more standardized than ant and has a rich set of plugins. But the million lifecycle phases with maven and the fact that it downloads the entire internet can be a little unnerving. On my next project, I'll be trying out gradle.

Continuous integration server - I really only have experience with Jenkins, but a variety of others exist. I've been quite happy with Jenkins, so I don't see myself switching any time soon.

Deployment tools - This is an important, but often overlooked category of automation tools. Maybe your deployment is simple, but it should absolutely be scripted, even if you write those scripts yourself. Just as with any of the other tools, your deployment infrastructure will evolve as your project does. 

Infastructure tools - Using virtual machines is a great way to make your infrastructure easier to manage. I've been using Chef for provisioning my VMs, and it makes reconfiguring and standing up new machines much easier. VMs are a great way to standup test environments as well. You may additionally want to look at infrastructure monitoring tools such as Nagios

Code quality control tools - cobertura code coverage, checkstyle, findbugs, pmd, CPD (copy-paste detector), and sonar.

This is just a sampling of the common tools I use. There are a seemingly endless number of solutions available in these areas. This may seem a bit overwhelming, and even if you can't use or don't need all of these tools, that's ok. The important part is to step into automation and quality control. The more you can get in place earlier in the project, the easier it will be in the long run.

Friday, July 20, 2012

Hamcrest Matchers

Hamcrest matchers have been available for some time now, but I still don't see them being used regularly on projects. If you're not familiar with them, they are set of matchers that can be used with JUnit's assertThat syntax to make assertions easier to read and easier to diagnose when there are errors. Consider a test where we want to test if an object is a string. A traditional JUnit assertion might look like
Object o; // assume this is set during the test)
...
assertTrue(o instanceof String);
The default failure message is AssertionError. I could make the error message more meaningful by adding an error message (this still won't work if o is null).
assertTrue("expected String but was " + o.getClass(), o instanceof String);
Hamcrest matchers take of this for us. The assertion can be rewritten as
assertThat(o,is(instanceOf(String.class)));
Now the error message is java.lang.AssertionError: Expected: an instance of java.lang.String got: <4%gt;. Note the is is just syntactic sugar and is optional. Hamcrest matchers also help to resolve the ambiguity between the expected and equals parameters. A typical assertion for comparing two strings might look like:
assertEquals(expected,actual);
The assertEquals method is easy to get wrong and reverse the actual expected, which will produce backwards error messages. Using the hamcrest matchers, rewrite this is
assertThat(actual, equals(expected))
All hamcrest matchers follow this pattern of assertThat(actual, matcher), which make them read fluently. More information about hamcrest matchers can be found http://code.google.com/p/hamcrest/wiki/Tutorial. If you're writing Java unit tests, these provide a nice addition to the library.