Wednesday, December 8, 2010

Eclipse Hot Swap Debugging

Maybe this is a well known feature, but it was news to me. The Eclipse debugger supports swapping code out at runtime when debugging (JVM 1.4 and later). Ensure Build Automatically is enabled, then run your application in debug mode. When stopped at a breakpoint, change the code you want to change and save the file. The code will be automatically swapped into your application without restarting - pretty cool.

This article http://www.ibm.com/developerworks/library/os-ecbug/ gives some more details regarding debugging with Eclipse.

Tuesday, June 1, 2010

Anti-Patterns

While most good software development teams have knowledge of software patterns, I still don't hear teams frequently talking about anti-patterns. I'm not really sure why that is. It seems logical to me that if patterns are a way of communicating common ways of doing things, anti-patterns should be in a programmer's language to communicate how not to do things, and to identify problematic areas of code. Anti-patterns do also extend beyond code into management, organization, etc, but I will just focus on coding anti-patterns.

One that I see so frequently is copy-paste-mutate. That is, when a developer copies a block of code, pastes it somewhere else, and changes it slightly. Most of it is duplicated and now mistakes are duplicates and testing must be duplicated (if you are testing). If you find yourself copying and pasting, stop. Should the functionality be in an abstract class? Should it be in a utility class? Regardless of where it needs to go, it shouldn't be copied and pasted.

Another recurring anti-pattern is see deals with poor exception handling. It's way too common to see e.printStackTrace() or LOGGER.error(e) (or even worse, an empty catch block) as a solution to error handling. If you can "handle" the exception by just printing it out, maybe it shouldn't be an exception at all. Exceptions should indicate errors (i.e. exceptional cases) and your program generally shouldn't be able to continue to operate normally when one occurs without proper handling.

Wikipedia has a large list of anti-patterns here http://en.wikipedia.org/wiki/Anti-pattern#Software_design_anti-patterns. Take a look and see which of these traps you're falling into.

Monday, April 26, 2010

Eclipse Templates

You may notice in Eclipse when pressing ctrl+space to auto-complete that you get suggestions that are not necessarily code. For example, you can select main to auto create a public static void main(String[] args) method. You can also define your own custom templates (and view all the existing ones) by going to Window > Preferences > Java > Editor > Templates.

This is a nice feature if you haven't used it before. I particularly like being able to define a println template for System.out.println to make it easy to switch between groovy and java. Another common one I define is a logger template to create a logger variable. If you find yourself defining the same lines of code in many places, a template may be of use to you.

If you already use templates, it would be nice to share some common ones you use.

Wednesday, March 31, 2010

Passive Views and View Interfaces

User interfaces are inherently difficult to test since logic buried in the GUI can't really be tested without bringing up the entire system, and this is not really practical for unit (or even integration) tests. It's common to say "Extract the logic outside the GUI" but in practice, I don't see it done as much as I think it should be.
First, let's distinguish between a passive view and and active view. An active view tends to register itself with the model, listen for changes, and update itself. The following code would be typical in an active view:

public class MyView {

public void init() {
model.addPropertyChangeListener(this);
}

public void propertyChanged(PropertyChangeEvent evt) {
String propName = evt.getPropertyName();
if ( propName.equals("prop1") ) {
updateViewWithProp1Change();
}
else if ( propName.equals("prop2")) {
updateViewWithProp2Change();
}
// ... etc ...
}
}

Typically the updateViewWithPropXXXChange methods would read the new value of the property and determine what to display on the view. To give a concrete example, imagine a view that updates a temperature display.

public void updateTemperatureDisplay(double newTempFarenheit) {
if ( mode.equals(FARENHEIT) ) {
tempLabel.setValue(Double.toString(newTempFarenheit));
}
else if ( mode.equals(CELSIUS) ) {
tempLabel.setValue(Double.toString(toCelsius(newTempFarenheit)));
}
}

In this example, the view does the conversion to Celsius. This logic is now difficult to test without showing the temperature display. This view is active. It's fast to write because the logic is contained in here, but difficult to test.
A passive view on the other hand can be thought of as a "dumb" view. It displays what it is told.

public interface MyPassiveView {
void setTemperatureText(String value);
}

public class MyPassiveVewImpl implements MyPassiveView {
public void setTemperatureText(String value) {
tempLabel.setText(value);
}
}
public class MyController {
private MyPassiveView view;

public void updateTemperatureDisplay(double newTempFarenheit) {
String temperatureText = "";
if ( mode.equals(FARENHEIT) ) {
temperatureText = Double.toString(newTempFarenheit);
}
else if ( mode.equals(CELSIUS) ) {
temperatureText = Double.toString(toCelsius(newTempFarenheit)));
}
else { // handle error }
view.setTemperatureText(temperatureText);
}

Now all the view does is set the label text. This is more work but the controller can be independently tested from the view. Notice in this example also the view implements an interface. View interfaces greatly simplify testability and make many of these patterns possible. I think this is frequently overlooked by developers and the view ends up being a concrete class.

There are various patterns that fall along this line, notably model-view-controller, model-view-presenter, and supervising controller all with varying degrees of passiveness. These can all be found on Martin Fowler's website (http://martinfowler.com/), and many other results can be found by a simple search.

Wednesday, March 17, 2010

Launching a process in groovy

Just a quick little groovy tid-bit here. If you've ever launched an external process in Java, you know what a pain it can be. Groovy makes it quite simple. You can execute a process from a string by using the execute method. A simple example would be "ls -al mydir".execute(). That's it.

Wednesday, February 17, 2010

Beware of the SwingWorker

The SwingWorker is a nice class for executing long running tasks behind that won't block the event dispatch thread, but it has its gotchas that can be difficult to track down. The one in particular that has been the most cause of pain for me is that it swallows exceptions in the doInBackground method unless you explicitly call the get method from the done method.

Consider this seemingly simple code

SwingWorker w = new SwingWorker() {
@Override
protected Object doInBackground() throws Exception
{
throw new RuntimeException("Catch me");
}
};
w.execute();

Of course this throws an exception, right? In fact, it doesn't (well, it does but it never bubbles up so it would go completely unnoticed).

The way to ensure the exception is thrown is by calling get in the done method.


@Override
protected void done()
{
try
{
get();
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
catch (ExecutionException e)
{
// throw the cause since the execution exception wraps the
// underlying exception
throw new RuntimeException(e.getCause());
}
}


It's an ugly solution though since the get method throws those checked exceptions but at least the exception gets thrown.

This is a very common problem when the swing worker is not returning any value and just performing a task, so you never call the get method.

Thursday, February 11, 2010

Difficulties of the Java clone method

Sometimes we have a need to copy objects. The clone method is a common way of doing that, but it is all too often misused. This post will discuss some common pitfalls and alternatives to cloning.

First, the Cloneable interface doesn't enforce any contracts. It has no methods. The clone method belongs to Object. Cloneable is just a marker interface to indicate that an object supports cloning. However, in order to make the clone method accessible to other objects, you need to make it public, since it is protected by default (and now all subclasses will have a public clone method, even if they are not directly cloneable since the visibility of the method can't be reduced, so be sure to implement clone for the subclasses).

Additionally, reading the clone method documentation a little more closely, it states the the following are generally true, but not requirements.
x.clone() != x
x.clone().getClass() == x.getClass()
x.clone().equals(x)

Even the stated contract of clone is quite vague, and there really is no guarantee of the object that will be returned. But working on the idea that we want a meaningful clone method, let's assume these will be true and move on to common problems with clone.

First, all objects in the hierarchy must implement clone, and you can't always control that. An implementation of clone will generally look like:

public class CloneMe extends NotCloneable implements Cloneable {
public CloneMe clone() {
try {
// This will fail if NotCloneable doesn't implement the clone method
CloneMe clone = (CloneMe) super.clone();

// copy the other fields
}
catch(CloneNotSupportedException e) {
// do something with the exception
}
}
}

It is difficult to copy objects in the object graph if they too don't
implement clone

public class CloneMe implements Cloneable {
private MyInterface obj;

public CloneMe clone() {
// try/catch omitted for brevity
CloneMe clone = (CloneMe) super.clone();
clone.obj = How can this be copied? We don't even know the type of MyInterface?.
Ideally use obj.clone(), but if it doesn't implement Cloneable, it's
impossible to make a deep copy (if the underlying type has a clone method,
it might be possible to reflectively invoke it).

}
}

Though the above example is illustrated by the fact that obj is an interface, it could have the same problem even if it is a non-final class.

Cloning lists and arrays must also clone the elements of the arrays

public class CloneMe implements Cloneable {
private Object[] myArray;
public CloneMe clone() {
CloneMe clone = (CloneMe) super.clone();
clone.myArray = Arrays.copyOf(myArray); // These arrays refer to the same elements
and modifying one's elements will modify the other's

}
}


Objects that implement clone can't clone final fields. Consider the class

public class CloneMe implements Cloneable {

private final Date myDate;

public CloneMe clone() {
// note: try/catch omitted for brevity
CloneMe clone = (CloneMe) super.clone();

// This won't compile since myDate is final
// This also illustrates a problem discussed above.
// What if date is actually a subclass of date? The clone and
// original objects will have different types for myDate.
clone.myDate = new Date(myDate.getTime());

}
}

Note: If the fields are completely immutable, they don't need to be clone since they can't be changed.

These are some of the major problems with clone, and Joshua Bloch discusses these points as well in Effective Java.

If you need to copy objects, what are the alternatives?

You could use copy constructors. However, copy constructors still have the problem that all of the objects being copied need to be deep copied as well. And since objects being copied may be a subclass of the declared type, the only way to copy them would be to reflectively invoke its copy constructor (if it has one).

You could write your own interface that has a copy method. It would function similarly to the clone method, but it would actually enforce some contract.

The best situation is to avoid object copying whenever possible (create totally new objects if needed). Favor immutability to avoid the need for clone and beware of the pitfalls and document well when copying is absolutely need it.

Tuesday, February 2, 2010

What to do when you find a bug

Inevitably you will find bugs in your code (yes, even you will write bugs). Once a bug has been identified, what steps do you take to fix it? Regardless of how small the bug is, it should be put into a bug tracking system (you do have one, right? If not, consider something free like Trac). This allows you to track bugs over time and do some deeper analysis.

Once the bug is identified, take steps to reproduce the bug by writing a test that exercises the bug. Then make the code change to fix the bug. Now you've fixed it and have a test to ensure it doesn't happen again.

This is where too many people stop. It is important to identify why the bug occurred. Was it an error in specifications? An error in coding logic? or some other error? Note this in the tracking system.

Periodically, query the bug tracking system to get an idea of why these bugs are happening (root cause analysis) and take the organizational steps necessary to correct them.

Monday, January 4, 2010

JUnit Assumptions

This is a new feature I just learned about. JUnit has a class called Assume which allows you to make assumptions about the environment you're running in. If the assumption is not true, then the test is ignored (that is the default test runner's behavior).
For example, sometimes I have tests that are operating system specific and don't necessarily make sense on other operating systems. Typically, I would do something like:

@Test
public void windowsSpecificTest() {
if ( System.getProperty("os.name").toLowerCase().contains("win") ) {
// do windows test
}
else {
LOGGER.warn("Test skipped because not on windows");
}
}

With the Assume class, you could do something like:

@Test
public void windowsSpecificTest() {
Assume.assumeTrue(System.getProperty("os.name").toLowerCase().contains("win"));
// do windows test. if this is windows, the test will be ignored.
}


This isn't earth shattering, but it's another nifty little trick.