Sunday, February 20, 2011

Greatest Weakness

I am sure, if you have been on even a single interview, chances are good that you have been hit with The Question. You know the one - the question that most everybody hates, and to which there is no real good answer out there. "What is your greatest weakness?" How are you supposed to come up with an answer to that question, when you are trying to make yourself look as good as possible to these people? And why the heck am I wasting time writing about a silly interview question inside of a tech blog?

Well, I have been thinking about this a lot recently, and it occurs to me that this question is actually one of the keys to being a good programmer. For example, think about that guy that most of us has met at least once - thinks he is God's gift to programming, when in actuality you wouldn't let him touch your code with a 10 foot pole. Programmers like this are severly handicapped by their own mental image of themselves - believing oneself to be God-like prevents you from confronting and overcoming your own limitations.

While this fact is true in other professions as well, in programming it is particularly important because there are concrete methods we can use to improve ourselves. You should constantly be looking at your own development as a programmer, and finding those places where you suck. Rest assured, there is some way in which you suck. Even the greatest programmer in the world sucks in some way. Find your suck, and fix it.

I am hardly the first person to think of this. Jeff Atwood's blog Coding Horror is one of the few blogs that I follow closely. He has a great many posts in this vein:

I think, though, that this can be taken beyond just being aware of your weaknesses. Really, I think, the key to improving as a developer is self honesty. As the Greeks say, Know Thyself. Try to get a good handle on what your strengths are, and what your weaknesses are. In fact, try to actually go so far as to write out a list of your strengths and weaknesses. Make them real weaknesses, too, not those cheesy, strengths-worded-as-weaknesses (i.e. "Sometimes I just work too hard and get too much done" - eck). As an example, I will expose my own lists in this area. Strengths:
  • I am quick - I can typically bang out changes at a quicker than expected pace
  • I am pretty good at debugging hard to figure out bugs
  • I am good at working with legacy systems and retrofitting bad code
Weaknesses:
  • Once I find a solution, I can latch onto it, and have a hard time leaving it for new solutions
  • I can be kind of absent minded, and forget things that are not directly part of my attention at the moment
  • I can overlook some edge cases when testing a system

Once you have your list, figure out what you are trying to do to overcome them:
  • Once I find a solution, I can latch onto it, and have a hard time leaving it for new solutions - so I sometimes, time permitting, try to discard a solution once I find it, and start from scratch, going in a different direction.
  • I can be kind of absent minded, and forget things that are not directly part of my attention at the moment - so I make sure to make heavy use of Outlook, both with the calendar and task lists, so that it reminds me to do stuff when I need it.
  • I can overlook some edge cases when testing a system - so I always try to spend extra time looking for edge cases, and sometimes ask others for opinions, to try to flush out my testing.

If you are really honest with yourself, and really understand where your strengths and weaknesses lie, you can make use of that both in your current job and in any future job interviews. By understanding yourself, you can know when and where you should volunteer for tasks, and where you should ask for help. And when you are in that interview, and the dreaded question comes up, you can give them one hell of a surprise by actually answering it with a real weakness, paired with your plan for strengthening that weakness - which may actually give you a heads up, as it will set you apart from all of the "I just care too much!" answers.

Thursday, February 10, 2011

Metadata Hell

I recently had the opportunity to attend JavaOne in San Francisco, which was a very great overall experience. One thing that I noticed, though, was the apparent love affair with annotations. It would seem that annotations are The Next Big Thing. In almost every session that I attended, there was some person going on and on about how great annotations are. Look, you can configure things on a single line! OOOH, you can configure properties in line with your code! Holy Crap, you can embed connection information into annotation tags directly in your java code!

No, I really was not kidding about that last one. Apparently, the new best practice in Java is to put all of your configuration information into annotations. By all, I really mean all configuration information, right down to your database connection strings. The very thing that I have been taught since I saw my first for loop, that which has been banged into me repeatedly as the worst danger in the world, is now best practice!

We are now hard coding this stuff in our code.

From what I can gather, this was put forth as the solution to what was commonly referred to as XML Hell. People didn't like all of the XML configuration that was having to occur to get applications running. I can understand this concern - XML files can be a pain in the rear end. I think, though, that the mark was missed a bit on this one. All we have really done is trade out one Hell for another.

My biggest concern with annotations is the unnecessary complication of the code files. Take the following example, taken from a Struts2 convention plug-in example:
package com.example.actions;

import com.opensymphony.xwork2.ActionSupport; 
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

@Results({
  @Result(name="failure", location="fail.jsp")
})
public class HelloWorld extends ActionSupport {
  @Action(value="/different/url", 
    results={@Result(name="success", location="http://struts.apache.org", type="redirect")}
  )
  public String execute() {
    return SUCCESS;
  }

  @Action("/another/url")
  public String doSomething() {
    return SUCCESS;
  }
}
Here is the exact same Action class, without the annotations:
package com.example.actions;

import com.opensymphony.xwork2.ActionSupport; 

public class HelloWorld extends ActionSupport {

  public String execute() {
    return SUCCESS;
  }

  public String doSomething() {
    return SUCCESS;
  }
}
That is a dramatic reduction in complexity, and that is just on a simple example application. What is more, it is now encouraged that every single third party library, framework, whatever, should now all use annotations. Look at the above code again: that is the added complexity from a single framework's configuration. What is going to happen when you have a framework and a handful of libraries and they all want to use different annotations?

The rub of it is, in my mind, that there was another solution available - simplify the XML. Having XML files isn't a problem; it provides a nice, isolated place to put the metadata of your application, keeping it separate from the logic of your application. However, most XML configuration is very complex, large, tree-like structures. Take, for example, the XML needed to configure a Java servlet:

    HelloWorld
    com.jspbook.HelloWorld


    HelloWorld
    /HelloWorld

Here is the annotation configuration version:
@WebServlet(name="HelloWorld", urlPatterns={"/HelloWorld"})
I can admit that the above configuration is more simple than the current configuration. However, here would be a proposed alternative in XML, which would also reduce it to a single line:
<servlet name="HelloWorld" urlPattern="/HelloWorld" class="com.jspbook.HelloWorld"/>
With that, you have the simplicity of a single line of configuration, but still safely tucked away in a separate XML file.

In fact, it is my theory that there is nothing that you can do with annotations that you can't do in just as few lines in an XML file. The only difference is that in the XML file you need to specify what class you are referring to. That is it.

In short, while I see the need for something to be done to reduce the configuration pains that we as developers currently experience, I absolutely do not think that the answer is to move that pain to a place where I have to stare at it and read through it every single day. There are other, better solutions out there, if we would but take the time to look for them.

Wednesday, February 2, 2011

Struts2 vertical radio list without custom template

I have seen a lot of questions sent out into the void of the internet, wondering how you could do something as simple in Struts2 as make a radiobutton list display vertically instead of the default horizontally. The answer always seems to be writing a custom template for it. While this is an effective solution, it often does not fit the problem at hand.

I had an issue not long ago where I had to put a radio list inside of a grid, interspersed with other form elements. In this case, writing a custom template with <br> tags after each radio button did not work. So I came up with another way of handling this pesky situation. It is not quite as elegant as writing a custom template, but it will get the job done.

Basically, what you have to do to lay the radios out vertically is to use multiple radio tags, each pointing to the same selector variable, each with a limited version of the actual list. Here is a simple example:
<s:radio name="valueField" list="#{'value1':'label1'}"/><br>
<s:radio name="valueField" list="#{'value2':'label2'}"/><br>
<s:radio name="valueField" list="#{'value3':'label3'}"/>
That will display one radio button per line, still connected as a single list. It will default if "valueField" is already set, and it will successfully post back into "valueField".

As a bit meatier of an example, take the following code. This code shows an Action class with a List of Objects, which we will then iterate over in the jsp page. This shows a more typical setup.

ListObject.java:
public class ListObject {
    private String key;
    private String label;

    public ListObject(key,label) {
        this.key = key;
        this.label = label;
    }

    public String getKey() {
        return this.key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getLabel() {
        return this.label;
    }

    public void setLabel(String label) {
        this.label = label;
    }
}
ListAction.java
public class ListAction extends ActionSupport {
    private List<ListObject> myList;
    private String mySelection;
    
    public String input() {
        myList = new ArrayList<ListObject>();
        myList.add(new ListObject("val1","label1"));
        myList.add(new ListObject("val2","label2"));
        myList.add(new ListObject("val3","label3"));

        mySelection = "val2";

        return INPUT;
    }

    public String execute() {
        // Do stuff with list here
        return SUCCESS;
    }

    public List<ListObject> getMyList() {
        return myList;
    }
    public void setMyList(List<ListObject> newList) {
        this.myList = newList;
    }

    public String getMySelection() {
        return mySelection;
    }
    public void setMySelection(String newSelection) {
        this.mySelection = newSelection;
    }
}
list.jsp

    <s:radio theme="simple" name="mySelection" list="#{key:label}"/> <br>


At the core of this method is the specifying of independent sublists for each radio tag. The syntax inside the list attribute is the way you specify an in place list - "#{'key':'value','key2':'value2'}". For our lists, though, instead of using string literals, we are pulling the values from our iterator. Inside an iterator tag, the iterator object is at the top of the value stack, so that just referencing the variable names of the data members of the object pulls out the value successfully. Then Struts magic takes care of combining all those radio tags with the same name to point to the single back end data member.

Creating custom templates can often be the better solution, but in situations where that doesn't work, this is a good way to go as well.

Tuesday, February 1, 2011

Creating a custom Struts2 validator

Recently I was working on a project which had a very specific validation requirement, that the Struts2 validation framework did not currently support. I had a dynamic collection of objects, and I needed to make sure that an attribute of that object was distinct across the entire collection.

I could have added a validate method to my action class and perform the validation there manually, but I wanted to keep everything in the xml validation. So I used the opportunity to learn how to write a custom Struts2 validator.

As it turns out, it is not nearly so complex as it sounds. To start things off, I created a new class that extended FieldValidatorSupport, since I wanted this validator to be a field validator. I then overrode the "validate" method, which does the actual validation. So here would be the very basic validator:
package my.package.name;

import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;

public class UniqueCollectionValidator extends FieldValidatorSupport
{ 
    @Override
    public void validate(Object object) throws ValidationException
    {
    }
}

I am going to jump ahead now and show you how to hook up said validator, because that comes into play in building the validator. So, first step in wiring up a custom interceptor is adding a file called validators.xml to your project's classpath. The contents of the file should look like this:

    


Second step is just referencing the validator. Open up your action's validation.xml file and add the following validator underneath the field you want it to apply to:


That is everything needed to wire up your custom validator. Now we get to the fun part - making your validator, you know, validate something. First off, and this is the part that needed the wiring in place to properly show, is adding parameters. As it turns out, you can add as many parameters to your validator as needed, and it does not take much. In this case, we need as a parameter the name of the attribute on the object that we need to be distinct.

First step to adding a parameter is to add the private member variable to your validator class, and give it getters and setters, like so:
package my.package.name;

import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;

public class UniqueCollectionValidator extends FieldValidatorSupport
{
    String uniqueFieldName = "";

    public String getUniqueFieldName()
    {
        return uniqueFieldName;
    }

    public void setUniqueFieldName(String uniqueFieldName)
    {
        this.uniqueFieldName = uniqueFieldName;
    }

    @Override
    public void validate(Object object) throws ValidationException
    {
    }
}

Once we have getters and setters in our validator, we populate them by simply adding those elements to our xml validator.

    <param name="uniqueFieldName">myUniqueFieldName</param>


All that is left now is filling in the details of the validator.
package my.package.name;

import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;

public class UniqueCollectionValidator extends FieldValidatorSupport
{
    String uniqueFieldName = "";

    public String getUniqueFieldName()
    {
        return uniqueFieldName;
    }

    public void setUniqueFieldName(String uniqueFieldName)
    {
        this.uniqueFieldName = uniqueFieldName;
    }

    @Override
    public void validate(Object object) throws ValidationException
    {
        String fieldName = getFieldName();
        Object val = getFieldValue(fieldName, object);
        
        List collection = null;
        List<String> soFar = new ArrayList<String>();
        
        if ( val instanceof List )
        {
            collection = (List) val;
        }
        else
        {
            return;
        }
        
        for ( Object obj : collection )
        {
            String toCheck = "";
            
            if ( this.uniqueFieldName.length() == 0 )
            {
                toCheck = (String) obj;
            }
            else
            {
                toCheck = (String) getFieldValue(this.uniqueFieldName,obj);
            }
            
            if ( soFar.contains(toCheck) )
            {
                addFieldError(fieldName, object);
                return;
            }
            
            soFar.add(toCheck);
        }
    }
}
This is kind of a lot of code to just dump on you, but most of it is pretty straightforward. There are just a few useful little bits to point out.

First off, when you enter a field validator, the object passed in contains the field parameter we are trying to validate against. In order to get the specific field we are dealing with, we use two member functions of FieldValidatorSupport - getFieldName and getFieldValue.
String fieldName = getFieldName();
Object val = getFieldValue(fieldName, object);
This gets for you the name of the field that we are validating against, and the current value of that field.

This validator can only work against List objects, so the first thing I do after that is make sure that it is a List, and cast the val appropriately. If it is not a List, then I just return without validating anything.
if ( val instanceof List )
{
    collection = (List) val;
}
else
{
    return;
}

At that point, I am able to move forward with my logic for determining uniqueness. The only other key piece of information here is the way to fail validation. If you hit the case where your validation fails, you can simply do the following:
addFieldError(fieldName, object);
return;
This will tell Struts that validation failed on this field, and it will use the normal method of choosing what message to display from the validation xml file.

That's all there is to it.