magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

Archive for ‘February, 2004’

I had some problems with this and found the documentation a little light on the ground, so I felt a little primer was in order.

So what is a proxy class?

Well, in Java terms a proxy class is a runtime-created class which acts like a class of a specified set of interfaces. “CGLIB”:http://cglib.sourceforge.net/ is capable of creating proxy classes without having interfaces – it can mimic a specific class.

Why would you want one?

In “Spring”:http://www.springframework.org (and other languages) proxy classes are used to allow the use of AOP interceptors. The proxy implementation calls the Interceptors before/after invoking the underlying object.

What is an Interceptor?

An Interceptor is a class which gets executed before, after, or around a method. By around we mean both before and after. Oh, and it can also be called when a method throws an exception.
Continue reading…

After looking for sometime at using XWork as a command driven framework for desktop clients, I decided to put that to one side for the moment to instead cooperate with “Keith Donald’s”:http://jroller.com/page/kdonald work on “Spring’s”:http://www.springframework.org/ Rich Client Platform (spring-rcp). As I mentioned before I was a little frustrated by XWork’s IoC framework – the fact that you had no control over how @Interceptor@, @Action@ or @Result@ objects were created. I started looking at the problem from the point of view of integrating Spring inside XWork, and ended up with the makings of a Command Framework completely implemented using Spring. The work’s very much at a prototype phase right now, and I’ll post more information as it comes together. I’m hopeful of getting it properly integrated with Keith’s first commits for spring-rcp, and as soon as I do I’ll post some example code.

After some badgering by “Simon”:http://www.brunningonline.net/simon/blog/, I’ve decided to start posting the occasional book review. As a voracious collector (and sometime reader) of books, I feel it is a duty to impart my knowledge on some matters, whilst at the same time whoring myself for a potential paid gig. Either that or to inflate my own sense of self importance, whatever.

Anyway, first up for treatment is Kent Beck’s “Test-Driven Development by Example(Test Driven Development – The Addison-Wesley Signature Series )”:http://www.amazon.co.uk/exec/obidos/ASIN/0321146530/qid=1077822818/sr=1-1/ref=sr_1_11_1/026-5985556-2226861. A rather slim tome in the context of computing books (which tend to value content over quality), it aims to describe the process of Test Driven Development (TDD for TLA fans) by a series of, you guessed it, examples. The first half shows the process being applied to solving a relatively straightforward use case. It succeeds well in managing to introduce the core processes of TDD, but at times the tone of false modesty Kent uses can really annoy me. I know enough of Kent Beck’s work to know that the guy cannot be as mediocre a programmer as he claims in the book, and for him to claim otherwise irks me somewhat.

The other problem the first section has is that in order to simply explain the TDD process, he has to use simple, small steps, which of themselves seem trivial and do not really help show some of the power of TDD. This can often be a problem with trying to describe computing technologies – by the time you’ve got an example simple enough to explain a technology, you’ve removed the need for using the technology in the first place.

Some of the early points are very well made however, this description being the single best argument for test cases I think I’ve ever seen:

In teaching TDD, I see this situation all the time – excellent software engineers spending 5 to 10 minutes reasoning about a question that the computer could answer in 15 seconds. Without the tests you have no choice, you have to reason. With the tests you can decide whether an experiment would answer the question faster. Sometimes you should just ask the computer.

At no stage during the first part is any guidance for setting up a TDD environment given. In addition, whilst JUnit is mentioned as the testing framework several times, no information is forthcoming as to how to run the tests yourself. This can be a bit frustrating to people who want to follow along with the examples from the beginning. This begins to be readdressed in the second part, where by way of a more advanced example, Kent decides to implement a JUnit type system using a TDD approach. In it you get a feel as to how JUnit works, but you still don’t actually know how to download, install and run it.

By choosing an advanced sample such as the implementation of a unit testing framework, Kent is clearly trying to kill two birds with one stone – describe JUnit and give a more advanced TDD example. He does of course make a rod for his own back – he is using the Unit testing framework he is creating (called xUnit) as the test framework itself. I’m sure many computer scientists get a hard-on for this self-referential coding but for my mind it needlessly complicates things.

Perhaps the most notable thing about this middle section of book is the change in programming language. The testing framework he develops is a written in Python. No doubt a boon for Python coders out there, this can’t but help make things a little awkward for those who picked the book up, saw the early sections are written in Java and thought this was the book for them. Likewise Python programmers may have some trouble understanding the Java examples in the initial sections, which would be required in order for them to follow the later Python code.

The real pay dirt for this book can be found in the final section. Here, Kent details a series of test patterns expanding on the early examples which give a fantastic overview of what you should test and how. For me, I found myself skipping much of the early stuff and focusing my attentions on these more complex topics, however I obviously lost out a little – I frequently found myself referring to the earlier chapters to better understand the topics being addressed.

Conclusion

All in all, Test-Driven Development can quite quickly explain to you what TDD is, and what its promises are. It does its best to extol its virtues, but I can’t help thinking that the only way to really be converted to TDD is to use it yourself. The lack of discussion on how to implement a TDD environment for yourself is disappointing, and the brief foray into Python confusing, however all in all this book is well worth a read for any of you interested in the topic.

I’ve looked over the initial work done to integrate “XWork with Spring(Support for resolving component References in external IoC containers such as Spring)”:http://jira.opensymphony.com/secure/ViewIssue.jspa?key=XW-122. That proposed solution just used Spring to resolve external components – an @ExternalReferenceResolver@ is used to provide named objects, and a Spring specific implementation is created to access and retrieve objects from Spring itself. Whilst this does solve some of the limitations of the current XWork form of IoC, this feels Ugly – you are taking an incredibly flexible IoC framework and using one little part of it, whilst keeping your own more limited framework. I would like to see the existing XWork API become a wrapper on top of Spring. By all means keep the existing XWork configuration format, but extend it to support Spring-like features. Use Springs Interceptor’s, its invocations – leverage all of Springs excellent existing code. Fair enough, XWork then just becomes a thin wrapper on top of Spring, but you’ll end up with a more flexible command-driven framework, which would in all likelihood find far more use outside of WebWork than is currently the case. Once done, you can then remove the need for @Interceptor@, @Action@ and @Result@ methods – Spring doesn’t need them.
Note that anything I say regarding Spring can equally be applied to another type 2 or 3 IoC container.

When you configure your XWork application (be-it WebWork or something else), you define your Action, Interceptors which intercept Action invocation, and Results, which get executed when an Action returns. You have complete control over the implementation of these classes – beyond the fact that you need to implement some basic interfaces (@Action@, @Interceptor@ and @Result@ respectively), however you have absolutely no control over how these classes get instantiated by XWork at runtime – internally XWork just gets your class, and calls @newInstance@. The limit of control you have over how Xwork sets these objects up is in the form of String/Value pairs defined in the configuration.

So why is this a problem? Well, lets take the example of my “Swing/XWork prototype(A GUI framework using XWork)”:http://www.magpiebrain.com/archives/000181.html I posted earlier. In it I created an Interceptor to monitor the progress of an Action. As the Action is invoked and completed, my Interceptor calls methods on a @ProgressRegister@ object. The problem is that I cannot pass references to my @ProgressRegister@ object into the interceptor when created – I am forced into creating a Singleton method accessor on @ProgressRegister@. In an ideal world, I would be able to define my @ProgressRegister@ object, and tell XWork that this object instance should be passed in whenever my interceptor is created:



...







This is of course exactly how IoC frameworks like Spring and Pico container work (the @bean@ definition from above is actually lifted straight from a Spring XML file). Ideally, XWork’s configuration could be overhauled to use Spring internally, but this is a big job. Instead I have a compromise.

Lets imagine an Interceptor class called @SpringInteceptorFactory@ which implements @Interceptor@. It takes a single string parameter which equates to the name of another Interceptor defined in a Spring config file. When invoked by XWork, @SpringInteceptorFactory@ creates an Interceptor of the relevant type (with properly wired dependencies) and executes it accordingly. This same solution could be used to create @Result@ or @Action@ objects. I can’t escape the feeling that adding yet another config file (in the shape of a Spring XML definition) is going to complicate things, however if you were already going to use Spring (Or Pico/NanoContainer) perhaps its not that much hassle after all.

Thanks to a “post(Swing Action Architecture)”:http://jroller.com/page/bhagvank/20040222#swing_action_architecture over at Bhagvan K’s blog, I found a link to an article covering an “action architecture for Swing(An Easy Architecture for Managing Actions)”:http://www.javadesktop.org/articles/actions/index.html. Of special interest to me is that fact that the code defines an XML format for storing action information:


It also defines groups of actions, for example for use on a menu:




      ...


My SwingCommandFactory needs to be able to load this kind of information – the id of the actions will probably resolve to the names of the XWork defined actions (I am unsure how/if to handle xwork namespaces as yet). Assuming the code is opensource, I might use the XML format and parsing code for my framework – although I’d like to combine this kind of configuration with xwork.xml, it will at least be a good stop gap solution.

I’ve been looking into this whole XWork + Swing thing a little more, and have come up with a fairly simplistic example of how a Swing+XWork framework might look. If you want to follow the code I suggest you read my brief “XWork tutorial(A Simple Xwork Example)”:http://www.magpiebrain.com/archives/000180.html. Anyway, my example shows a simple window with a button and a progress bar. When clicked, the button invokes an XWork Action on a thread. A ProgressInterceptor records when the action starts and ends, and changes the state of the onscreen progress bar as appropriate.

The Action has to be run on a seperate thread, as otherwise it will be invoked on the Event thread, blocking any GUI updates until the action has returned. This means that the return from Action‘s execute method cannot be handled – we have moved from synchronous action invocation to asynchronous action invocation. The ProgressInterceptor calls methods on aProgressRegister singleton to tell it when an Action has started or stopped. I dislike the use of a singleton, but right now it is impossible to pass objects into an Interceptor (this is a nasty constraint of XWork – I might see how easy it would be to use Spring to create Interceptors). A ProgressListener gets registered with the ProgressRegister, and updates a JProgressBar as required.

Its actually a lot simpler than it sounds – check the code for yourself to see. It represents an afternoon of work so is a little rough and ready – you’ve been warned! To run the program the main class is org.magpiebrain.example.TestProgram. The code requires webwork1.0, OSCore, OGNL and commons-logging to run, all of which are included in the zipfile. If I decide to take this much further I will look into supporting SWT, so suggestions as to how easy this would be are welcome. Note that the only GUI feedback from the action is by the progress bar at present – I need to think about the interaction between the result of the Action and its impact on the GUI a little more.

I’ve been playing around with “XWork”:http://wiki.opensymphony.com/space/XWork a little today, attempting to work out how it all hangs together. I thought I’d share a simple XWork example I worked up as it should give you a simple introduction to the internals of XWork.

Scenario

We want to invoke a bit of code and return a result. We would like to provide transparent logging.

The Action

First, we define the action


public class ExampleAction implements Action {
    public String execute() {
        return "Done";
    }
}

The execute method will get invoked, and will return a value. We have to extend Action which I do not like, and we also throw exception form our exectue method which I dislike hugely, but understand the reasons for both.

The configuration

We define a config which declares our action, and defines the inteceptors we will use. “Interceptors”:http://wiki.opensymphony.com/space/Xwork+Interceptors are objects that get invoked before and after the action does. We are going to use two standard interceptors, one to log the action, the other to time it. We define an InterceptorStack which we can reuse – an InterceptorStack is simply a set of Interceptors that get invoked.











Now define our action and configure the use of the debugStack




Invoke the action

Very simple this:


try {
  ActionProxy proxy = factory.createActionProxy("default","TestAction", null);
  String result = proxy.execute();
  System.out.println("Calling action returns " + result);
} catch (Exception e) {
   //handle
}

For the future

I’m going to look at creating a Swing framework that uses XWork. I can already feel an UndoRegistrationInterceptor coming on…

[Updated 18:45 22-02-2004]: Jason Carreira pointed out that I don’t need to create an ActionInvocation from my proxy, I can exectue the Proxy directly. The code has been changed accordingly.

[Updated 19:31 22-02-2004]: Jason Carreira pointed out other bonehead mistakes – updated 🙂

[Updated 19:31 22-02-2004]: Code fix – thanks to Brian Buckley.

Thanks to a comment from Jason Carreira made on my “post(Thoughts on an MVC framework for Swing)”:http://www.magpiebrain.com/archives/000178.html, I was pointed in the direction of XWork. XWork is a view agnostic command pattern framework, originally developed as the core of “WebWork 2”:http://wiki.opensymphony.com/space/WebWork2.
XWork is a little different to my design – here actions are not the thing that does something, they signify the intention to do something. Additionally actions can be intercepted by Interceptors before being run.

Components are not fully de-coupled from the framework itself – when writing your own Action for example you have to subclass the Action interface. There is also no concept of a view as such within XWork – this is left to specific uses of XWork (such as WebWork). In general XWork seems close to my suggested design, but not as flexible. It would probably benefit from being reworked to use a more fully featured IoC engine internally (such as Spring or Pico) which would then allow coupling to the framework to be removed. That said its highly unlikely I would ever be able to develop something as fully featured as XWork on my own. I’ll have a play tonight and see whats involved in getting a simple Swing interface to use XWork – that will be a proper test of just how flexible it can be.

Rational

There are many MVC web frameworks, but as far as I can see there are very few MVC frameworks for Swing (I actually don’t know of any, but there might be some out there). Outlined here is the rough design for one. Please note that this is in the very early stages of design, no code exists for it, and I might not do anything with it. Comments are nonetheless appreciated.

The View

The view would be a GUI Interface. Each view would provide the data necessary to perform some action – it might be a simple ‘OK’ button, or it could be a full blown multi-tabbed interface.

Mapping to an action

Our views cannot themselves perform a submit to an associated action – they know nothing of the action itself. On their own, they are of little use. If we take the view that a view can map to only a single action at any time, we could pass in contextual information to the view to handle submits. Here, a MappingContext object encapsulates this particular form/action mapping.


public class ExampleView {
  private MappingContext _mappingContext;

  public ExampleView(MappingContext context) {
    _mappingContext = context;
  }

  ..

  public void submit()
  {
    _mappingContext.submit(this);
  }
}

The advantage of this is that we can put our submit code wherever we like. A disadvantage is that a view instance can only be coupled to one action at a time. I am unsure as to whether or not this is actually a problem or not. We are coupling to an interface here, introducing a dependency to the underlying framework. I don’t like this, but cannot think of a way out of this at the moment, other that using AOP to generate the submit method. Using AOP might work, but I am unsure how to support submission to different action classes Dependant on the current context of the view – some further reading on AOP might enlighten me.

As for actually getting the view to display, well that would be achieved using a little bit of proxy magic. We do not want to enforce that our implementation implements interfaces, or worse still that it needs to be a Component subclass. Instead, we just create a method to return a displayable object, and in our framework configuration we’ll tell the controller what method to invoke to get it.
The controller will do this by creating a “Dynamic Proxy object”:http://java.sun.com/j2se/1.3/docs/guide/reflection/proxy.html#examples to wrap our form.

The Action

Our action is responsible for processing a view input, performing something, and returning a result. Our action implementations do not need to implement any interfaces. The web application framework can detail which method should be the entry point for the action, or a default can be assumed. Above we called submit on our MappingContext . Behind the scenes we are invoking are creating a Dynamic Proxy object to wrap the action class and provide an interface suitable for our framework.
We could overload our entry point method in order to handle submits from several views:


public ExampleAction {
  public void submit(ExampleView view) {
    //handle view
  }

  public void submit(AnotherView view) {
   //do something else
  }
}

And this will be handled by the framework.

The controller

The controllers job is to read the configuration, and produce the View/Action instance mappings when requested. This is clearly a task for an IoC framework. Configuration could be a simple XML file:







The display attribute tells the controller which method it should call on the view to get the displayable component, and similarly submit details the method to call on the action to invoke it. Of course, sensible defaults could be used.

Had you noticed?

That none of this is actually bound to Swing? Or any display technology? The display method that you create on your view can return anything you like – you just have to be in a environment that can display it. For Swing, another framework would wrap this and assume that the Object is a Component. I have the feeling I’ve reinvented something else out there, or else this is useless. Feedback would be appreciated.