Liskov vs Hibernate

Development, Java 2 Comments »

In Data Abstraction and Hierarchy, SIGPLAN Notices 23,5 (May, 1988) Barbara Liskov wrote;

What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.

and the Liskov substitution principle (LSP) was Born.

Applied diligently the LSP is one of the more powerful modeling techniques in an application designers bag of tricks. Unfortunately it’s also one of the most frustrating and difficult to grok because it seems so simple and intuitive.

When applying the principle it should be seen from the interface clients point of view. So “the behavior of P is unchanged”, doesn’t mean that the program has the same effect on the world, it means that the caller doesn’t have to condition its interaction with the subject based on whether they are o1 or o2. To the client both objects fulfill the contract and the client can ignore the differences between them.

Lets say I’m asked to provide a list interface (let’s pretend that java.util.List doesn’t exist for now). The client requires three operations; get an item at a specified index; put and item in a specified index and size that returns the greatest value for index. I create my interface and an implementation or two and deliver it to the world to great fanfare.

    +------------------------------+
    | List<T>                      |
    +------------------------------+
    | <T> get(int index)           |
    | <T> put(int index, <T> item) |
    | int size()                   |
    +------------------------------+

Another group requires a similar interface, the only difference being that they don’t want the list to be modifiable. Seeing as the original List interface was so successful I’m asked to create the new ImmutableList without the put operation.

    +------------------------------+
    | ImmutableList<T>             |
    +------------------------------+
    | <T> get(int index)           |
    | int size()                   |
    +------------------------------+

Several months later I’m reviewing my library and I notice that the two list interfaces share a common set of methods and I decide to redefine List to inherit from ImmutableList and unthinkingly violate the LSP.

    +------------------------------+
    | ImmutableList<T>             |
    +------------------------------+
    | <T> get(int index)           |
    | int size()                   |
    +------------------------------+
                   ^
                   |
    +------------------------------+
    | List<T>                      |
    +------------------------------+
    | <T> put(int index, <T> item) |
    +------------------------------+

You see from the standpoint of an ImmutableList client a List isn’t an ImmutableList as it can be modified. The inheritance relationship allows a List to be used wherever an ImmutableList is specified. Thus a client expecting that the list will not change may function incorrectly if when a List instance is supplied.

So how does this relate to Hibernate? Hibernate allows you to specify persist your java model with minimal impact on your code (this is grossly simplified view but will allow me to illustrate my point). It manages the relationships between objects and can be configured to either load an object graph completely, lazily or a combination of both. This is achieved by substituting the referenced classes with Hibernate proxies. These proxies will then load an objects details as required. Hibernate also allows you to detach and reattach and object from it’s data source. When an object is detached attempting to access parts of the object graph that haven’t been loaded results in an exception being generated.

Not so long ago I was involved with a project that used Hibernate to persist it’s state. The model was relatively small but the data set was very large. The data was organized into hierarchies. A node could have many children, these children could also have children (think massive XML document). A single node could literally have millions of descendants. Eager loading the complete graph for any node simply wasn’t an option and as the objects needed to be sent over the wire lazy loading was out. The team had developed a number of queries that would load part of the tree to a specified depth to suite the callers purpose. The problem was that the caller had to know which query had been used to load the object and adjust their behavior accordingly, violating the LSP. The team had effectively created derivative classes that behaved differently. This manifested itself in subtle (and not so subtle) defects, the solution to which was often to add additional queries to service the specific client needs.

To be fair the problem wasn’t really hibernates fault, but by the way it was being used (give someone enough rope …). Developers must be constantly vigilant to ensure their im implementation choices don’t introduce subtle design flaws.

Interface Assertions

Java 2 Comments »

For some time I’ve wanted to be able to define basic contracts for interface clients in a stricter manner than simply specifying the client constraints in javadoc. The problem is that interfaces can’t provide implementation so the constraints can’t be applied in the interface but instead must be applied in the implementations. This leads to duplication of the constraint logic and make it easy to omit these checks when implementing the service. Good test design and coverage will detect and expose the problems but it would be better if we could prevent the problem in the first place.

Below is a simple service that manages a collection of users. There are a number of simple client constraints, such as not passing null or empty strings to findUser, that are captured in the javadoc. What we want to do is enforce these across all implementations.

/**
 * A service to manage user accounts
 */
public interface UserService {
	/**
	 * Locate the user.
	 *
	 * @param id the id of the user to locate. Must not be null or empty
	 * @return the located user or null if a user with the supplied id is not found.
	 */
	User findUser(String id);

	/**
	 * Remove the user from the system. If the user does not exits the request is ignored.
	 *
	 * @param id the id of the user to remove. Must not be null or empty.
	 */
	void removeUser(String id);

	/**
	 * Store a user instance. If the user already exists the record is updated, otherwise a
	 * new record is created.
	 *
	 * @param user the user to store. Must not be null.
	 */
	void storeUser(User user);
}

In-line assertions

When it comes time to implement the interface you need to be aware of the client contract constraints and implement them via assertions or run-time exceptions. I like assertions so I’ll use them to add the rules around my implementation TransientUserService. The first version will simply add these constraints directly to the implementation.

public class TransientUserService implements UserService {

	private Map _users = new HashMap();

	public User findUser(String id) {
		assert null != id && id.length() > 0 : “An id must be supplied”;
		return _users.get(id);
	}

	public void storeUser(User user) {
		assert null != user : “A user must be supplied”;
		_users.put(user.getId(), user);
	}

	public void removeUser(String id) {
		assert null != id && id.length() > 0 : “An id must be supplied”;
		_users.remove(id);
	}
}

Nothing surprising here, the assertions are diligently applied in a simple and consistent manner. When a second implementation or subclass is created the assertions are once again added, again in the third and fourth implementations and so on. I find this duplication of code undesirable so what other options exist.

Wrapper Assertions

The next implementation wraps a user service instance and enforces the assertions before delegating to a concrete implementation.

public class UserServiceAssertionWrapper implements UserService {

	private final UserService service;

	public UserServiceAssertionWrapper(UserService service) {
		assert null != service : "the UserService must be supplied";

		this.service = service;
	}

	public User findUser(String id) {
		assert null != id && id.length() > 0 : "An id must be supplied";
		return service.findUser(id);
	}

	public void removeUser(String id) {
		assert null != id && id.length() > 0 : "An id must be supplied";
		service.removeUser(id);
	}

	public void storeUser(User user) {
		assert null != user : "A user must be supplied";
		service.storeUser(user);
	}
}

This approach reduces the amount of duplication as the rules are captured in a single class that applies the assertions before proceeding. It does however mean that we must remember to wrap all of our instances in the wrapper before providing them to clients. The can be made easier with using a dependency injection framework or factories but at some point it will be forgotten and the contract wont be enforced.

Injection via Aspects

Aspect orientated programming provides us with an additional solution. Until java has support for design by contract (DBC) I believe that inserting contract constraints via aspects is the cleanest and most robust approach. The idea is simple. As part of the interface create an aspected that provides pointcuts that pick out all implementations of the interface methods and advice that injects the contract constraints.

/**
 * A service to manage user accounts
 */
public interface UserService {
	/**
	 * Locate the user.
	 *
	 * @param id the id of the user to locate. Must not be null or empty
	 * @return the located user or null if a user with the supplied id is not found.
	 */
	User findUser(String id);

	/**
	 * Remove the user from the system. If the user does not exits the request is ignored.
	 *
	 * @param id the id of the user to remove. Must not be null or empty.
	 */
	void removeUser(String id);

	/**
	 * Store a user instance. If the user already exists the record is updated, otherwise a
	 * new record is created.
	 *
	 * @param user the user to store. Must not be null.
	 */
	void storeUser(User user);

	static aspect UserServiceConstraints {
		pointcut findUser(UserService service, String id): execution(User UserService.findUser(String))
			&& target(service)
			&& args(id);

		pointcut removeUser(UserService service, String id): execution(void UserService.removeUser(String))
			&& target(service)
			&& args(id);

		pointcut storeUser(UserService service, User user): execution(void UserService.storeUser(User))
			&& target(service)
			&& args(user);

		before(UserService service, String id) : findUser(service, id) {
			assert null != id && id.length() > 0 : “An id must be supplied”;
		}

		before(UserService service, String id) : removeUser(service, id) {
			assert null != id && id.length() > 0 : “An id must be supplied”;
		}

		before(UserService service, User user) : storeUser(service, user) {
			assert null != user : “A user must be supplied”;
		}
	}
}

In the above code the pre-conditions for calling UserService methods have been added via an inner static aspect. This keeps the contract and interface nice and close to each other. Implementations have the pre-conditions applied via the before advice consistently without any need to manually wrap the service instances. The service definition and constraints are both documented and coded in the same file making it easier to keep them in sync as the interface evolves. The interface and aspect can be contained in a separate library and you can use aspectj’s binary weaving at either compile or run-time (though I prefer compile time application of advice in most circumstances) to apply the advice. As a bonus if you use eclipse and the AJDT the editor will mark each point that the aspect is applied and you can use the cross references view to see where an advice is applied or what advice applies to the block of code you’re looking at.

Other Contract Assertions

Although the example above only enforces a few pre conditions, it’s not hard to add simple post conditions and invariants. For example after successfully adding a user we should be able to find that user via the service. The advice below implements the rule.

		after(UserService service, User user) returning : storeUser(service, user) {
			assert null != service.findUser(user.getId()): "User must be able to found after being added";
		}

Final Note

With this new approach it’s easy to get carried away. There is a fine line to be carefully walked between what rules you add via contract advice and the rules checked and asserted for in unit tests. Whenever I create an interface I create an abstract unit test that validates implementations. Contract advice doesn’t remove the need for these tests.

The great Derby slowdown

Development, Java 1 Comment »

We recently switched our client database implementation from Mckoi to Derby due to some performance issues we’d run into. All was going well, performance was up significantly and everyone was happy, that was until Friday when one of the developers noted that performance had dropped a little then promptly went on holidays :).

It wasn’t until today that I got around to integrating the new database into the client application. Once I did I pulled some customer information from the server onto the client and waited, and waited, and waited, then the sinking feeling came. First I checked to see if I’d done something lame, like turned off the turbo switch (anyone else remember when PCs had turbo switches?), nope, everything pretty much checked out. Bum.

So out comes the trusty profiler, Yourkit, odd name, great profiler. Quick run through with yourkit collecting profiling information and it was apparent that we were compiling statements far more often than we should have been. The code seemed to be doing the correct thing. We use prepared statements almost everywhere, still the database log and yourkit where showing that each time the statement was used it was being recompiled.

Okay time to attach the Derby source and set a couple of breakpoints to get a better idea about what was going on. Nope the Derby source is compiled without debug symbols. That’s okay, it’s open source, I can recompile it myself. Now I’m only going to say one thing about the whole sordid process. Any ant build that has a property named sane that must be set to false to get the build to work has some very serious issues.

Now, finally, after the shock and horror of building Derby, I begin to trace execution. There are some prepared statements, there they are getting cached, all good. Let the application run and enter the area running slowly, what, the cache is empty, huh? I saw statements in there just a moment ago. Trace, click follow, ooohhh. It seems that one of the last little optimisations / sanity checks added by my holidaying colleague before departing, was to drop a constraint before running a series of operations. It was then added back (the database is accessed by a single user on a single thread) once everything was done. Unbeknown to him once you make a DDL manipulation call in a Derby transaction no statements will be cached and every call recalculates the plan. Eeeks, a minor modification to drop and restore the constraints in separate transactions did no end of good.

Derby’s documentation could have been a little clearer. It states that the following must be true for the prepared statement to be cached:

  • The text must match exactly
  • The current schema must match
  • The Unicode flag that the statement was compiled under must match the current connection’s flag

Obviously we were violating the second point. It didn’t occur to me because the manipulation is done once at the start of the operation and the schema is the same for all calls after that. There is no mention of the fact that no statements will be cached until the transaction manipulating the schema commits. At least with the source available I was able to trace through and locate the cause.

Cedric is wrong.

Java 2 Comments »

I’m a big fan of Cedric Beust’s work but in “Testing private methods? You bet.” Cedric asserts that private methods should have tests because “if it can break, test it”. In my opinion this is just plain wrong and I believe that Cedrics own examples back me up.

Cedric provides us with a reasonably common scenario.

Imagine that you are writing a Swing table widget that lets you order your columns in several different ways. Your sorting algorithm is private and one day, you introduce a bug in it. If all you do is test the public methods, the widget will simply start showing wrong results and your tests won’t tell you anything more. For all you know, there might be a bug in your Swing code. If you unit test your (private) sorting algorithm, you will catch the error right away instead of wasting time “higher up the stack”.

This is variant on a theme that we’ve all come across. In the past I’ve seen people expose private methods as public just to test them and these methods then become a part of the public contract of the class. Funnier is the public method with a note in the javadoc that the method is really private and only exposed for testing purposes. Better yet is the use of reflection to call the a private method to test it. I could go on but I’m guessing you get my point.

My rule is simple. If it’s part of the public contract, test it, if it’s internal implementation, test is via the public contract.

So we now go back to Cedric’s problem. From the description doesn’t this sound like the perfect place to use a strategyy? Cedric’s need for a sorting algorithm sounds like an ideal place for a sorting strategy. You can then test your sorting algorithm simply and easily external to it’s usage in the widget. This breaks the design down neatly but still leaves us with a dangling pointer. The sorting strategy class is now a stand alone class that is not really part of the public contract of the application. We could make the class package protected and have the test in the same package but I like to have my tests in a separate package to ensure that I am just testing the public contract. So following the lead of the eclipse team, I put classes like this, ones that need to be public for implementation purposes but are not a part of the public contract in their own package, internal. Eclipse can even enforce that I don’t directly use classes found in any internal package.

In my opinion Cedric’s solution tests a bad design. No amount of testing will “fix” it. If you need to test a private method look at your design. If the method should be part of the public contract then make it so. If not, take another look at the design of your classes.

Solving the Eclipse slowdown on MacOS X

Eclipse, Java, Mac No Comments »

I love my Mac but using Eclipse can be painful at times. It slows down to the point it’s unusable and the problem seems to have gotten worst recently. So today, after watching my CPU jump to 100% usage every-time I typed or scrolled I did a bit of a scan of the Eclipse bug list to see if I could find an answer.

Bug 95475 sounded like a good place to start, a good number of other mac users complaining about the same thing as I was experiencing. I began to read through the comments. A few made mention of the fact that the slowdown occurred after running a swing application. I realized that this was also true in my case (I’m working on a swing application for corporation x). Then I read this comment.

I’ve been trying to pay more attention to this “slowdown” problem and quantify it a bit and since
yesterday, I’ve had some interesting observations. I started on 3.0 (3.0.1?) and had it running for a
couple of days without doing much (powerbook was slept a couple of times).

Then, after using it for a period of time, maybe an hour, I noticed that scrolling was slow. I timed it,
using the menubar clock. Clicking in the “page down” part of the scrollbar, it took about 2 seconds
after I clicked before it would actually scroll.

So I launched Quartz Debug to see if it was in a redraw loop, as a previous comment suggested and the
strangest thing happened. I noticed that after I launched Quartz Debug and turned on “Flash screen
updates”, the speed in Eclipse was just fine.

Throughout the rest of the day, every 15-30 minutes it would become slow for typing and scrolling
again. Simply launching and then quitting Quartz Debug returned the performance in Eclipse to
normal. I was able to repeat this at least 3 or 4 more times.

Finally, at the end of the day, I upgraded to Eclipse 3.1RC1. Today, the same thing happened in
3.1RC1, and again launching and quitting Quartz Debug fixed it.

Sure enough launching Quartz Debug sped things back up for me.

So now I have Quartz Debug in my launcher panel. A quick run and quit every so often keeps Eclipse singing. It doesn’t solve the problem, but it certainly makes life better. Now I have no excuse not to get a 17″ powerbook ;)

Necessitas 0.3.0

Eclipse, Java, Necessitas 4 Comments »

An updated version of Necessitas (0.3.0) is now available.

Changes (in no particular order):

  • updates the the core ivy implementation to 1.1
  • allows you to specify (using a comma seperated list) the configurations to use (* or all will be used by default).
  • will detect a local ivyconf.xml at the project root and use it instead of the default provided by ivy
  • if update on change is selected the classpath will be recalculated if the ivyconf.xml is changed

Note: Ivy 1.1 checks the internet for property updates when it starts up. This may lead to slow eclipse startup times. There is a patch to stop this but I didn’t want to release against a unstable build of ivy. Once a stable version is available I’ll release a quick update.

You can download the latest version via the eclipse update manager from http://eclipse.oneill.id.au/updates/

“Open source is way more fun”

Eclipse, Java, Random thoughts No Comments »

In a recent interview the principal architect of SWT, Steve Northover, had the following to say

As a developer who has worked on both closed and open source projects all I can tell you is that open source is way more fun. For example, when you fix a bug, you really make someone happy. The feedback is instantaneous. There’s also a great feeling about working in the open. However, these are just my opinions. Personally, I like open source but I don’t presume to tell other people what to do or speculate on corporate strategy.

I couldn’t agree more.

The Java Module System

Java, Necessitas No Comments »

JSR 277: Java Module System proposes to end “JAR hell”. The plan is to replace the current JAR/WAR/EAR system with something that supports versioning, metadata and dependency specification. It draws on what has been learned from technologies such as .NET Assemblies, OSGI, Eclipse and Netbeans.

The JSR is attempting to create a reliable mechanism for expressing, resolving, and enforcing the dependency of one module upon another. It’s goals are admirable, JAR hell has been a pain in the side of anyone who has had to deal with application servers that expose classes from versions of jars (for no good reason other than plan dumb ass lazyness) that aren’t compatible with your module. So JSR 277 aims to help us by:

  • Adding explicit versioning of both the module and it’s dependency declarations
  • Providing a repository for storing and retrieving modules on the machine with versioning and name space isolation support (it’s unclear if they mean on the current machine are something more global)
  • Adding runtime support in the application launcher and class loaders for the discovery, loading, and integrity checking of modules.
  • Allowing you restrict what is exposed to other modules by your module.

It all sounds great, the proof will be in the pudding though and I’ll be keeping a close eye on this one. Unfortunately we wont be seeing it in our applications until around 2007. For now at least we have ivy for build time dependency management.

Jacket 0.3 released

Jacket, Java No Comments »

I’m happy to annouce that version 0.3 of Jacket is ready and available from the usual location.

The release is mainly focused on increased documentation. There are a couple of minor changes in the base xml handling but nothing that will break current code.

Release Features:

  • Added lots of Javadoc
  • Added a short introduction (access via the package description)
  • Use Ivy for dependency management

Upcomming Features

  • REST service support

A copy of the introduction has been posted if you just want to get a feel for how it’s used without downloading the full release.

Introducing Jacket

Jacket, Java No Comments »

Jacket is a very simple package for handling Document/Literal SOAP messages. The intent is to keep the
framework out of the way and allow the programmer to process the XML components of the message.

The Client

To invoke a SOAP service the first thing you need is a SoapClient.
The client is used to invoke RequestHandler or
SoapRequestHandler objects. It handles the transport of the payloads,
negotiating things like proxies, the handlers do the payload processing.

Creation is pretty simple.

SoapClient client = new SoapClient();

If you need to go through a proxy then you just need to supply the configuration

ProxyConfiguration proxy = new ProxyConfiguration(new ProxyHost("proxy", 3128));
SoapClient client = new SoapClient(proxy);

Now that you have a client all you need is a request handler.

Request Handlers

RequestHandler instances do the payload processing. The prepare the body of
the request and respond to the result. A SoapRequestHandler also allows
you to specify processing for header elements.

public class DilbertRequest extends SoapRequestHandler

{
        static final String NAMESPACE = "http://tempuri.org/";
        static final String TARGET = "http://www.esynaps.com/WebServices/DailyDiblert.asmx";
        static final String ACTION = "http://tempuri.org/DailyDilbertImagePath";

        String _imagePath;

        public DilbertRequest() throws URISyntaxException
        {
                super(new URI(TARGET));
        }

        public String getImagePath()
        {
                return _imagePath;
        }

        public String getAction()
        {
                return ACTION;
        }

        public boolean hasRequestBody()
        {

                return true;
        }

        public void writeRequestBody(XMLStreamWriter request) throws XMLStreamException
        {
                request.writeStartElement("DailyDilbertImagePath");
                request.writeDefaultNamespace(NAMESPACE);
                request.writeEndElement();
        }

        public void readResponseBody(XMLEventReader response) throws XMLStreamException
        {
                DilbertResponseReader reader = new DilbertResponseReader(new StringValueCallback()
                {
                        public void value(String value)
                        {
                                _imagePath = value;
                        }
                });
                reader.read(response);
        }
}

In the above sample (that gets a link to todays Dilbert cartoon) we simply:

  • Provided the target url via the constructor and action by overridding SoapRequestHandler.getAction()
  • Tell the SoapClient that we have some information to send with the request by overridding RequestHandler.hasRequestBody() and write it in the overridden RequestHandler.writeRequestBody(XMLStreamWriter).
  • Read the result by overridding RequestHandler.readResponseBody(XMLEventReader)

Running

Now all we need to do now is invoke our request

DilbertRequest request = new DilbertRequest();
client.invoke(request);
System.out.println("Todays Dilbert can be found at: " + request.getImagePath());

Now wasn’t that simple?

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in