Wednesday, March 4, 2009

Unit Testing Java and Groovy with JUnit

As new frameworks pop up it pleases me to see how much emphasis is placed on writing automated tests. In Rails and Grails you almost need to go out of your way to opt out of writing tests (as you generate components for your application, test stubs are automatically created for you as part of the process). Unfortunately, far too many professional developers still do not write even the simplest automated tests as part of their software development tasks. Another common problem I see is developers who are new to testing in this manner who insist on creating test methods with a dozen or more assertions in a single individual unit test. I could probably write several posts on this topic and still only scratch the surface of what’s available in this space but I’ll try to focus this one on some simple guidance for someone who’s new to automated testing.

In an effort to keep things as simple as possible I’m purposely staying away from more complex topics (Mock Objects for example). If this post proves popular, I’d be happy to devote more time writing about this topic in greater detail (software quality is something I’m very passionate about). I’m going to use the same example from my last post on interoperability for this post since the domain model is pretty simple to understand and it demonstrates what I consider to be a very simple approach to writing unit tests.

For this example, our domain consists of three classes, a Customer class, an Address class, and a PhoneNumber class. In order to give us something relevant to test, I added a helper method to the Customer class and also to the Address class (the PhoneNumber class has only simple getters and setters). Let me take the opportunity now to say that I’m not a big fan of having unit tests for simple getter and setter methods even though many popular IDEs will generate these for you as part of generating a testing template. My definition of a simple getter or setter in this context is one you used the IDE to generate and that you have NOT further modified (no custom logic). If you’re new to advanced IDEs and professional Java development you should familiarize yourself with the proper way to generate these getter/setter methods from the IDE menus and NEVER create these methods manually. Many frameworks and tools in the Java space work under the assumption that your code conforms to a standard java beans format. If you mistype of even worse use the improper case for a single letter in one of your method names it can cause problems for frameworks that make this assumption (hibernate for example).

The relationship between these three classes is as follows: A customer can have zero or one address. An address can have zero or one PhoneNumber. In the customer class, I’ve added a single helper method (returnFullName) which simply returns the customer’s full name in the format ‘firstName lastName’. In the address class, I created a simple helper method which returns a single line string with the full address flattened out.

I like to think I’m pragmatic when it comes to testing software. There are many schools of thought around testing and one of them: test driven development is extremely popular right now (also a bit controversial in some circles). Given what I typically see when interacting with the average IT shop I’d be happy if the team is writing tests at all.

Before we get into the examples, let’s discuss the general guidance I’d like to offer. This is by no means a comprehensive list – not even close. I’m hoping to provide just a few quick tips which IMO will help to improve the quality of the tests you write. In no particular order they are:

1. Use factory classes to generate your test data.

2. Use constants (public static final) for values in your factory classes.

3. Usually (I try not to say ‘Always’ when it comes to software) an individual unit test should focus on testing a single concern (if your test has more than a few assert tests, it’s probably worth a closer look to see if you might need to break things up a bit).

4. The name of a test method should be descriptive enough to tell others what you’re trying to test.

Let’s take a look at the domain classes we’re hoping to test:

Customer.java

   1: package org.demo;
   2:  
   3: /**
   4:  * A sample customer domain class implemented as a java class
   5:  * @author twalters
   6:  */
   7: public class Customer {
   8:     private String firstName;
   9:     private String lastName;
  10:     private Address address;
  11:  
  12:     public Address getAddress() {
  13:         return address;
  14:     }
  15:  
  16:     public void setAddress(Address address) {
  17:         this.address = address;
  18:     }
  19:  
  20:     public String getFirstName() {
  21:         return firstName;
  22:     }
  23:  
  24:     public void setFirstName(String firstName) {
  25:         this.firstName = firstName;
  26:     }
  27:  
  28:     public String getLastName() {
  29:         return lastName;
  30:     }
  31:  
  32:     public void setLastName(String lastName) {
  33:         this.lastName = lastName;
  34:     }
  35:  
  36:     /**
  37:      * This method returns a fully formatted name for this customer.
  38:      * @return - a string of the format 'firstName lastName'
  39:      */
  40:     public String returnFullName(){
  41:         if ("".equals(this.getFirstName())  this.getFirstName() == null)
  42:             return this.getLastName();
  43:  
  44:         if ("".equals(this.getLastName())  this.getLastName() == null)
  45:             return this.getFirstName();
  46:         
  47:         return this.getFirstName() + " " + this.getLastName();
  48:     }
  49:  
  50: }

Address.groovy

   1: package org.demo
   2:  
   3: /**
   4:  * This is a simple domain model class for a snail mail address.
   5:  * @author twalters
   6:  */
   7: class Address {
   8:     String addressLine1
   9:     String addressLine2
  10:     String city
  11:     String State
  12:     String postalCode
  13:     PhoneNumber phone
  14:  
  15:     /**
  16:     * Returns the address formated as a single line string.  If line1, city, state, or postal code are null,
  17:     * the entire string will return null
  18:     **/
  19:     def String formattedAddress() {
  20:         if (addressLine1 == null  addressLine1 == "" 
  21:             city == null  city == ""  state == null  state == "" 
  22:             postalCode == null  postalCode == "")
  23:             return null;
  24:  
  25:         if (addressLine2 != null && addressLine2 != "")
  26:             return addressLine1 + " " + addressLine2 + " " + city + ", " + state + " " + postalCode
  27:         else
  28:             return addressLine1 + " " + city + ", " + state + " " + postalCode
  29:     }
  30: }
  31:  

PhoneNumber.java only contains simple getters and setters and thus we’ll exclude it from this example at least as far as unit tests are concerned.

The first class I’d like to unit test is the Address domain class. Logically, I would typically lean toward testing the Customer first since it’s at the top of the food chain but that’s exactly why I’ve chosen to not test that one first (since it has an address field, I’d prefer to make sure my address class is working properly before worrying too much about the customer). When I pulled this together I actually practiced TDD (simply stated I wrote a test which failed, then I added logic to my domain to make the test pass) but for this example, the thought process is more important than the tactical approach I took.

In the address class, there are several simple fields (since it’s a groovy class the simple getter/setters are generated as needed). There is one special helper method in this class which must be tested. The purpose of this method is to flatten out an address into a single string field. In order to test this method, we must understand the requirements a bit better. For example, what should this method return when one or more of these fields are not filled in with data. If you think about a real world address, it’s pretty standard for the second address line to be empty but the other fields are typically required. To keep things nice and simple we’ll allow the consumers of this method decide what to do when one of these fields is blank. The method will simply return null if any of the fields are null or empty (except for address line 2 which can be null or empty). Now that we’ve clarified the expected behavior of this method, let’s move on to the next step.

At this point, I could crack open a unit test class and try to write a test to see how far I get before getting stuck. Since, I know that I’m testing a simple domain object, past experience tells me that I’m going to need a way to easily (and consistently) generate some test data in order to properly test the method. Let’s start with a simple test factory class for the address.

I typically name this type of factory class using a convention similar to this: ‘domainNameFactory’ (alternatively you could use a convention of: ‘domainNameTestFactory’). In our example this first factory is named AddressFactory. In general the idea behind a factory class of this type is to provide a static method which contains an instance of the class and returns it to the caller (populated with seed data). We’ll add a public static method to this new class named ‘getTestAddress’. I typically use a name similar to this to make it perfectly clear that this method does more than return an empty object instance. The remainder of this class is pretty self explanatory but I do want to point out one other thing here. I like to define all of the sample data at the top of the class as public static final fields. If this factory grows over time to provide multiple methods which create customers in different ways it’s often useful to have these variables defined in a single place at the top of the class (makes it easier to change a value later). It’s also handy as I often use these public static final fields in the unit test class as part of my assert tests. Here’s the AddressFactory class:

   1: public class AddressFactory {
   2:     public static final String ADDRESS_LINE1 = "First";
   3:     public static final String ADDRESS_LINE2 = "Second";
   4:     public static final String CITY = "City";
   5:     public static final String STATE = "State";
   6:     public static final String POSTAL_CODE = "Postal Code";
   7:  
   8:     public static Address getTestAddress(){
   9:         Address address = new Address();
  10:         address.setAddressLine1(ADDRESS_LINE1);
  11:         address.setAddressLine2(ADDRESS_LINE2);
  12:         address.setCity(CITY);
  13:         address.setState(STATE);
  14:         address.setPostalCode(POSTAL_CODE);
  15:  
  16:         return address;
  17:     }
  18: }

One cautionary note about using public static final fields to define your data. If your field is a complex object type (customer has an address field for example) just remember that we’re dealing with Java here and declaring a complex object as public static final prevents someone from reassigning the reference to a new one but it does NOT prevent you from changing one of the fields within the complex object.

Now that we have our AddressFactory class, let’s generate some unit tests. In thinking through our requirements, it’s clear that this method should in the case of the happy path return the full address with spaces and/or commas between the fields. It’s also clear that we need to test what happens when each of the fields provided isn’t filled in. It’s also important to remember that not being filled in could mean the field is null or it could mean that the field contains an empty string. Even if the language will default a field to one or the other if it’s never set via code you should never assume this value is always there since our application code could potentially null out a field or set it’s value to an empty string. In addition to having the proper tests for each of these scenarios, these tests should:

1. utilize the factory to get sample data

2. have names which makes it clear to someone else what the method is trying to test

Here are the methods I created for this class:

   1: public class AddressTest {
   2:  
   3:     private Address address;
   4:  
   5:     public AddressTest() {
   6:     }
   7:  
   8:     @BeforeClass
   9:     public static void setUpClass() throws Exception {
  10:     }
  11:  
  12:     @AfterClass
  13:     public static void tearDownClass() throws Exception {
  14:     }
  15:  
  16:     @Before
  17:     public void setUp() {
  18:         address = AddressFactory.getTestAddress();
  19:     }
  20:  
  21:     @After
  22:     public void tearDown() {
  23:     }
  24:  
  25:     @Test
  26:     public void testReturnFormattedAddressFullPopulated() {
  27:         String expResult = AddressFactory.ADDRESS_LINE1 + " " +
  28:                 AddressFactory.ADDRESS_LINE2 + " " + AddressFactory.CITY + ", " +
  29:                 AddressFactory.STATE + " " + AddressFactory.POSTAL_CODE;
  30:         String result = address.formattedAddress();
  31:         assertEquals(expResult, result);
  32:     }
  33:  
  34:     @Test
  35:     public void testReturnFormattedAddressWithNullLine2() {
  36:         address.setAddressLine2(null);
  37:         String expResult = AddressFactory.ADDRESS_LINE1 + " " +
  38:                 AddressFactory.CITY + ", " +
  39:                 AddressFactory.STATE + " " + AddressFactory.POSTAL_CODE;
  40:         String result = address.formattedAddress();
  41:         assertEquals(expResult, result);
  42:     }
  43:  
  44:     @Test
  45:     public void testReturnFormattedAddressWithEmptyLine2() {
  46:         address.setAddressLine2("");
  47:         String expResult = AddressFactory.ADDRESS_LINE1 + " " +
  48:                 AddressFactory.CITY + ", " +
  49:                 AddressFactory.STATE + " " + AddressFactory.POSTAL_CODE;
  50:         String result = address.formattedAddress();
  51:         assertEquals(expResult, result);
  52:     }
  53:  
  54:     @Test
  55:     public void testReturnFormattedAddressWithNullLine1() {
  56:         address.setAddressLine1(null);
  57:         String expResult = null;
  58:         String result = address.formattedAddress();
  59:         assertEquals(expResult, result);
  60:     }
  61:  
  62:     @Test
  63:     public void testReturnFormattedAddressWithEmptyLine1() {
  64:         address.setAddressLine1("");
  65:         String expResult = null;
  66:         String result = address.formattedAddress();
  67:         assertEquals(expResult, result);
  68:     }
  69:  
  70:     @Test
  71:     public void testReturnFormattedAddressWithNullCity() {
  72:         address.setCity(null);
  73:         String expResult = null;
  74:         String result = address.formattedAddress();
  75:         assertEquals(expResult, result);
  76:     }
  77:  
  78:     @Test
  79:     public void testReturnFormattedAddressWithEmptyCity() {
  80:         address.setCity("");
  81:         String expResult = null;
  82:         String result = address.formattedAddress();
  83:         assertEquals(expResult, result);
  84:     }
  85:  
  86:     @Test
  87:     public void testReturnFormattedAddressWithNullState() {
  88:         address.setState(null);
  89:         String expResult = null;
  90:         String result = address.formattedAddress();
  91:         assertEquals(expResult, result);
  92:     }
  93:  
  94:     @Test
  95:     public void testReturnFormattedAddressWithEmptyState() {
  96:         address.setState("");
  97:         String expResult = null;
  98:         String result = address.formattedAddress();
  99:         assertEquals(expResult, result);
 100:     }
 101:  
 102:     @Test
 103:     public void testReturnFormattedAddressWithNullPostalCode() {
 104:         address.setPostalCode(null);
 105:         String expResult = null;
 106:         String result = address.formattedAddress();
 107:         assertEquals(expResult, result);
 108:     }
 109:  
 110:     @Test
 111:     public void testReturnFormattedAddressWithEmptyPostalCode() {
 112:         address.setPostalCode("");
 113:         String expResult = null;
 114:         String result = address.formattedAddress();
 115:         assertEquals(expResult, result);
 116:     }
 117:  
 118: }

Each test in the above example is 4-6 lines long and tests a single condition. Some of you might not agree with me to split each of these scenarios up into a separate test but I just think it makes your test scripts easier to read and to verify for completeness (a non technical user could read the method names and determine if your test coverage seems sufficient). Also notice that I’m using the setUp method to regenerate a valid happy path customer before firing each individual unit test. By setting things up this way I no longer care what the other tests are doing to my in memory object because it is reset to a known state before each test is executed.

Now let’s move over to the Customer domain class. There are some requirements which would need to be clarified for this helper method also (for example, what does the user expect to happen if the first name is empty but the last name isn’t?) Using a pattern similar to our address testing we’ll create a CustomerFactory class to create a valid happy path customer for us. Here it is:

   1: public class CustomerFactory {
   2:     public static final String FIRST_NAME = "First";
   3:     public static final String LAST_NAME = "Last";
   4:  
   5:     public static Customer getTestCustomer(){
   6:         Customer customer = new Customer();
   7:         customer.setFirstName("First");
   8:         customer.setLastName("Last");
   9:         customer.setAddress(AddressFactory.getTestAddress());
  10:         return customer;
  11:     }
  12: }

Notice in this one that we’re leveraging the AddressFactory to create a valid address to associate with our customer. If you didn’t see the benefit of the Factory before it should a bit more apparent now (trust me it’s a huge time saver for larger test bases). Given the same general advice about watching out for null as well as empty strings, here is the test class for our customer domain:

   1: public class CustomerTest {
   2:  
   3:     private Customer customer;
   4:  
   5:     public CustomerTest() {
   6:     }
   7:  
   8:     @BeforeClass
   9:     public static void setUpClass() throws Exception {
  10:     }
  11:  
  12:     @AfterClass
  13:     public static void tearDownClass() throws Exception {
  14:     }
  15:  
  16:     @Before
  17:     public void setUp() {
  18:         customer = CustomerFactory.getTestCustomer();
  19:     }
  20:  
  21:     @After
  22:     public void tearDown() {
  23:     }
  24:  
  25:     /**
  26:      * Test of returnFullName method, of class Customer.
  27:      */
  28:     @Test
  29:     public void testReturnFullName() {
  30:         String expResult = CustomerFactory.FIRST_NAME + " " + CustomerFactory.LAST_NAME;
  31:         String result = customer.returnFullName();
  32:         assertEquals(expResult, result);
  33:     }
  34:  
  35:     @Test
  36:     public void testReturnFullNameNullLastName() {
  37:         customer.setLastName(null);
  38:         String result = customer.returnFullName();
  39:         String expResult = CustomerFactory.FIRST_NAME;
  40:         assertEquals(expResult, result);
  41:     }
  42:  
  43:     @Test
  44:     public void testReturnFullNameNullFirstName() {
  45:         customer.setFirstName(null);
  46:         String result = customer.returnFullName();
  47:         String expResult = CustomerFactory.LAST_NAME;
  48:         assertEquals(expResult, result);
  49:     }
  50:  
  51:         @Test
  52:     public void testReturnFullNameEmptyLastName() {
  53:         customer.setLastName("");
  54:         String result = customer.returnFullName();
  55:         String expResult = CustomerFactory.FIRST_NAME;
  56:         assertEquals(expResult, result);
  57:     }
  58:  
  59:     @Test
  60:     public void testReturnFullNameEmptyFirstName() {
  61:         customer.setFirstName("");
  62:         String result = customer.returnFullName();
  63:         String expResult = CustomerFactory.LAST_NAME;
  64:         assertEquals(expResult, result);
  65:     }
  66:  
  67: }

Saturday, February 28, 2009

Interoperability Between Java and Groovy

This week I continued to learn a bit more about Groovy and the value it can add to an enterprise Java application. In the past, one of the first questions I often pondered when thinking about the use of dynamic languages within the JVM was how feasible it would be to make calls from Java to the dynamic language and back again. Since as a general rule everything is an object in a dynamic language, I wondered in how many cases would you be forced to invoke methods from Java where the return type would simply be a generic ‘Object’ type. This week I focused my attention on how this seems to work in Groovy. I’m happy to report that thus far the answer is quite well!

In fact it works so well that aside from a different compiler (groovyc instead of javac), a consumer of a groovy class wouldn’t know the class is a groovy class unless they open up the source code. I’m thrilled to see how seamless this appears to be (at least in the simple cases I’ve implemented thus far). To illustrate what I found when I dug into this just a bit I created three simple domain classes. The first two, ‘Customer’ and ‘PhoneNumber’ I coded in Java. The third, ‘Address’ I coded in Groovy. In this very simple example, a customer can have zero or one address (customer has a simple getter and setter for the address field) and an address can have zero or one phone number associated with it. To illustrate what it looks like to work with java and groovy together, I created a simple test harness class which instantiates a new Customer and sets all of it’s properties (both java and groovy) by using standard java beans setter syntax.

First the Customer Java class (note the Address reference which is a groovy class):

   1: public class Customer {
   2:     private String firstName;
   3:     private String lastName;
   4:     private Address address;
   5:  
   6:     public Address getAddress() {
   7:         return address;
   8:     }
   9:  
  10:     public void setAddress(Address address) {
  11:         this.address = address;
  12:     }
  13:  
  14:     public String getFirstName() {
  15:         return firstName;
  16:     }
  17:  
  18:     public void setFirstName(String firstName) {
  19:         this.firstName = firstName;
  20:     }
  21:  
  22:     public String getLastName() {
  23:         return lastName;
  24:     }
  25:  
  26:     public void setLastName(String lastName) {
  27:         this.lastName = lastName;
  28:     }
  29:  
  30:     /**
  31:      * This method returns a fully formatted name for this customer.
  32:      * @return - a string of the format 'firstName lastName'
  33:      */
  34:     public String returnFullName(){
  35:         if ("".equals(this.getFirstName())  this.getFirstName() == null)
  36:             return this.getLastName();
  37:  
  38:         if ("".equals(this.getLastName())  this.getLastName() == null)
  39:             return this.getFirstName();
  40:         
  41:         return this.getFirstName() + " " + this.getLastName();
  42:     }
  43:  
  44: }

Here is a simple Address Groovy class (note the PhoneNumber reference which is a Java class):

   1: class Address {
   2:     String addressLine1
   3:     String addressLine2
   4:     String city
   5:     String State
   6:     String postalCode
   7:     PhoneNumber phone
   8:  
   9:     /**
  10:     * Returns the address formated as a single line string.  If line1, city, state, or postal code are null,
  11:     * the entire string will return null
  12:     **/
  13:     def String formattedAddress() {
  14:         if (addressLine1 == null  addressLine1 == "" 
  15:             city == null  city == ""  state == null  state == "" 
  16:             postalCode == null  postalCode == "")
  17:             return null;
  18:  
  19:         if (addressLine2 != null && addressLine2 != "")
  20:             return addressLine1 + " " + addressLine2 + " " + city + ", " + state + " " + postalCode
  21:         else
  22:             return addressLine1 + " " + city + ", " + state + " " + postalCode
  23:     }
  24: }

Finally, Here is a test harness that shows how you would consume both classes:

   1: //customer is a java class
   2: Customer customer = new Customer();
   3: Address address = new Address();
   4: customer.setFirstName("Travis");
   5: customer.setLastName("Walters");
   6:  
   7: //phone number is also a java class
   8: PhoneNumber phone = new PhoneNumber();
   9: phone.setAreaCode("111");
  10: phone.setLocalLeft("222");
  11: phone.setLocalRight("3333");
  12:  
  13: //address is a groovy class
  14: address.setAddressLine1("101 Test Address Way");
  15: address.setAddressLine2("Suite 2001");
  16: address.setCity("Richmond");
  17: address.setState("Virginia");
  18: address.setPostalCode("12345");
  19:  
  20: //consuming a java class from a groovy class
  21: address.setPhone(phone);
  22:  
  23: //consuming a groovy class from a java class
  24: customer.setAddress(address);

I left out the unit tests and supporting files from this post in the interest of keeping the posting brief (you all write unit tests right?). Actually, I still run into engineering teams who don’t write automated tests of any fashion more often than I would like. I’m planning to write up an intro to basic unit testing for my next post and I’ll use the simple unit tests I wrote as part of this exercise as examples for that post. If you’re new to automated unit testing check it out.

Tuesday, February 24, 2009

Processing XML in Groovy

Working with XML in Groovy is a real pleasure when compared with more traditional statically typed languages (Java, C#). Groovy provides a couple of different mechanisms for processing XML but for this post I’ll focus on the XMLSlurper class. To illustrate how simple it is to consume XML let’s look at a simple example XML stream:

   1: <customer>
   2:     <firstName>Joe</firstName>
   3:     <address>
   4:         <addressLine1>1111 Test Address Way</addressLine1>
   5:         <addressLine2>co test address</addressLine2>
   6:         <city>Columbus</city>
   7:         <state>TN</state>
   8:         <postalCode>22333</postalCode>
   9:     </address>
  10:     <address>
  11:         <addressLine1>2222 Test Address Street</addressLine1>
  12:         <addressLine2></addressLine2>
  13:         <city>Centerville</city>
  14:         <state>TX</state>
  15:         <postalCode>33444</postalCode>
  16:     </address>
  17:     <address>
  18:         <addressLine1>3333 Yet Another Address Avenue</addressLine1>
  19:         <addressLine2>Suite 222</addressLine2>
  20:         <city>Salem</city>
  21:         <state>VA</state>
  22:         <postalCode>44555</postalCode>
  23:     </address>
  24: </customer>

For the first example, we’ll simply assign a string variable equal to this multi line string field (In groovy the way to indicate a multi line string is to use the triple quote symbol). Once we’ve assigned the xml to a string we’ll consume the xml elements and print them to the console.

   1: def customerXMLData = 
   2:     """<customer>
   3:             <firstName>Joe</firstName>
   4:             <address>
   5:                 <addressLine1>1111 Test Address Way</addressLine1>
   6:                 <addressLine2>co test address</addressLine2>
   7:                 <city>Columbus</city>
   8:                 <state>TN</state>
   9:                 <postalCode>22333</postalCode>
  10:             </address>
  11:             <address>
  12:                 <addressLine1>2222 Test Address Street</addressLine1>
  13:                 <addressLine2></addressLine2>
  14:                 <city>Centerville</city>
  15:                 <state>TX</state>
  16:                 <postalCode>33444</postalCode>
  17:             </address>
  18:             <address>
  19:                 <addressLine1>3333 Yet Another Address Avenue</addressLine1>
  20:                 <addressLine2>Suite 222</addressLine2>
  21:                 <city>Salem</city>
  22:                 <state>VA</state>
  23:                 <postalCode>44555</postalCode>
  24:             </address>
  25:         </customer>"""
  26: def customerXML = new XmlSlurper().parseText(customerXMLData)
  27:  
  28: println("Customer's first name: " + customerXML.firstName)
  29: customerXML.address.each{address ->
  30:     println("Address:")
  31:     println("     address line 1: " + address.addressLine1)
  32:     println("     address line 2: " + address.addressLine2)
  33:     println("               City: " + address.city)
  34:     println("              State: " + address.state)
  35:     println("        Postal Code: " + address.postalCode)

To expand on this a bit further, we can now move the xml into an external text file. With a very simple change to our test code we can process this same xml from a file instead as the following example illustrates.

   1: def customerXMLData = new File("D:\\temp\\Customer.xml")
   2: def customerXML = new XmlSlurper().parse(customerXMLData)
   3:  
   4: println("Customer's first name: " + customerXML.firstName)
   5: customerXML.address.each{address ->
   6:     println("Address:")
   7:     println("     address line 1: " + address.addressLine1)
   8:     println("     address line 2: " + address.addressLine2)
   9:     println("               City: " + address.city)
  10:     println("              State: " + address.state)
  11:     println("        Postal Code: " + address.postalCode)

Note how simple it is to read the data from a file. If you were writing this code for a production environment, you would likely want to wrap the new File instance in a try catch block and catch the file not found exception and handle it gracefully. One of the benefits of Groovy over Java is that it allows you to decide whether or not you want to deal with these exceptions (if the file you’re reading is the web.xml file for example it’s probably safe to assume it’s always there in a production site and may not warrant the extra try/catch block. The other difference to point out in this last example is the method on line 2 changed from ‘parseText’ to simply ‘parse’. parseText is meant to work specifically with strings where parse is much more flexible and can work with a url or a file.

Sunday, February 22, 2009

The second coming of NetBeans

I’ve been a die hard eclipse user for several years now. A couple of years ago, I wanted to learn about some of the newer features of the Java language (my day job was pinned down to version 1.4.2 of Java – thanks BEA). I set out to work a bit with generics and also with the latest web service stack available at the time (metro).

I’ve been a long time listener of the Java Posse podcast and the topic of NetBeans and the new features it provides is a regular topic of discussion because one of the posse (Tor Norbye) is one of the key code committers on the NetBeans code base. I decided to give netbeans a new look since it had been years since I had last used it.

I started off by publishing and consuming a few web services using eclipse to get a baseline. I then downloaded the latest version of NetBeans (6.0 at the time – at the time of this writing 6.5 is stable and 6.7 is due out very soon). To keep things simple and to ensure that I had everything I might need, I chose to download the uber large version of the installer (couple of hundred meg download). I then used this version of the IDE to build a few web services as well as test consumers of the services. I came away thoroughly pleased with the experience. The IDE worked perfectly right out of the box and provided some very nice links for tutorials on the web which I found to be extremely helpful in spinning up on the new language features I was interested in.

I came away impressed but not sold quite yet. After all, most of what I had done was to build a couple of toy examples. The IDE performed beautifully but at work I was working with in a very large shop where everyone used Eclipse and I was able to complete the same tasks using eclipse (though I found NetBeans much easier to use).

During this same time period I’d been working quite a bit with Ruby on Rails using the Aptana plug-in for eclipse as my IDE of choice to work with Ruby. At the time it was working ok but was still pretty spotty with intellisense and getting the debugger to work had been quite a challenge. Several folks I worked with at the time had expressed an interest in learning more about Rails and so I decided to spin up a nice group project to give us all the chance to work and learn together. Several of the folks working with me on this pet project were brand new to eclipse and to Rails and they experienced considerable problems in getting a usable environment setup.

Given my positive experience with NetBeans in some of the Java R&D I had been doing, I decided to give it a try for Rails to see how well it would work when compared to my current eclipse setup. Since I had already downloaded the uber version of the IDE, I had everything that I needed for Ruby support. I was pleasantly surprised to find that NetBeans seemed to work pretty well right out of the box. My experience here was so positive that I immediately stopped using eclipse for my Rails work and switched over full time to NetBeans. During this time I also evaluated TextMate since everyone who owns a Mac says it’s the greatest editor ever created. I’m sure there’s no end to the number of people who would disagree with me on this but I just prefer a full featured IDE to an expert user editor. I still use TextMate on my Mac quite a bit for general purpose editing but not for writing code (if I really wanted to memorize all of those hot key combos, I’d just go back to the vi editor I used in college).

Now flash forward another year. Over the past week, I decided to learn a bit about Groovy since I hadn’t previously written any code using this language. I haven’t been coding much Java over the past 7 months (been working with .Net) so I decided to start out with a clean development environment. I downloaded the newest version of eclipse (GANYMEDE), groovy, the groovy plug-in for eclipse and followed the instructions on the main groovy site to set things up. I was able to create a working grails project but the IDE was giving me quite a bit of trouble in general (every time I move the mouse past the tool bar icons I get a null pointer exception from Java). Further, I was unable to set a breakpoint in a .groovy file (double clicking in the left margin did nothing for me). I fought with this for about 1/2 day before deciding to try NetBeans to see how it compared. As it turns out support for Groovy in NetBeans is still relatively new but it IS supported beginning with version 6.5. Since my old install was at this point out of date, I upgraded to the 6.5 release. Just like my previous two experiences, NetBeans just worked right out of the box. Even better, one of those nice tutorial links on the welcome page took me through something identical to what I was trying to do (calling from Java to Groovy and back again).

I hate to say it but… Three strikes and you’re out Eclipse! I’ll be using NetBeans for all of my Ruby, Groovy, and eventually Scala development. I also plan to try NetBeans on my next Java gig to see how it holds up in an enterprise development environment. If you haven’t used NetBeans in a while I’d strongly encourage you to check it out.

Back in the Saddle…

After a few weeks of distractions, I’m ready to get back into some technology work and along with that should be some time to post a few blog entries. I’ve been thinking a bit more about dynamic languages as of late and have decided to spin up on Groovy. Over the next few weeks, I’ll share my experience as I learn to work with Groovy and the Grails framework.

I’d like to start things off with a tribute of sorts to a good friend and co-worker I lost a year ago to cancer. The following write up is an article authored by Steve Metsker in reference to Groovy and the name chosen for the language. Enjoy!

=============================

Instead of using Java, we could all be using Vulcan today. That is, I think we’d be using Vulcan if, in the late 1970’s, the creators of the first object-oriented programming language had called their language “Vulcan.”

When techies try to introduce new technology, it helps (a lot) if the technology sounds strong, logical, and powerful. Unfortunately the creators of what I might have called “Vulcan” named their creation “Smalltalk.”

The penchant for self-destructive marketing is a subject to which I will return, when I get to the latest great innovation in programming languages, a language named “Gladiator”.

I worked as a Vulcan (well, Smalltalk) consultant for four years in the early 90’s. Other than its name, a huge difference between Vulcan and Java is that Java places a large emphasis on developers entering into their program lots of information about exactly which kind of object each object is.

To program in a “Customer” object in Java, for example, the developer must decide way up front all the details about exactly how this object will work. Can it report its name? Address? Credit limit? Java wants all these questions answered the moment you get going with Customer. Vulcan is way more relaxed, and lets developers start using Customer objects without ever specifying just how Customer objects work. Vulcan is a “dynamic” language.

It turns out that dynamic languages make developers much more productive. That is, anyway, the consensus of the speakers at the recent “No Fluff Just Stuff” conference that I recently attended. And I agree.

In my view, all that specification of Customer and other objects is like having training wheels on my bike. The training wheels can serve a purpose, but once I become expert they slow me down, and prevent certain maneuvers I’d like to make. I would also concede that all those declarations about how Customer objects work will actually eliminate about 5% of the testing I’ll need to do. But that 5% is not worth the loss of flexibility that the training wheels provide.

Dynamic languages are on the rise. “Ruby,” in particular, has been gaining market share steadily, especially since the advent of “Rails,” that gives Ruby developers an easy way to develop web pages with Ruby logic underneath.

You might, though, have a big investment in Java. Your developers might already know Java, and you might have software like “WebSphere” that makes it easy to create web services with Java. It would be really nice to have a training-wheels-free version of Java that would be super easy for Java developers to learn, and that would work with all of our existing Java applications. Such a language now exists, it’s free, it works, and it’s called “Gladiator.”

Well, unfortunately, and I hate to admit this, but the creators of Gladiator actually named it something else. They named it “Groovy.” Deep sigh. Boy, I’m afraid that will make it a lot harder for me to convince you that Fortune 500 companies should start using Gladiator. But they should.

Gladiator lets you ignore all those commitments that Java wants you to make, about how you’ll use your objects. The result is that Gladiator programs let you write, typically, about 25% of the programming code that a corresponding Java program would take. It’s fast, light, lean, mean and sits on top of your current Java technology, so it can go (and go fast) anywhere that Java takes you now.

Gladiator is the way of the future, I’m sure, which was something the developers of Vulcan also foresaw. Unfortunately – and it is hard to quantity the full loss we will endure from this self-destructive bent—Gladiator Instead of using Java, we could all be using Vulcan today. That is, I think we’d be using Vulcan if, in the late 1970’s, the creators of the first object-oriented programming language had called their language “Vulcan.”