Further webworking

I’ve posted a straight copy of my ANT build file for Webwork up here.

The project is just something I was toying with as an excuse for learning Webwork & Castor – its vapour at the moment – don’t expect a Roller-killer anytime soon 🙂

I’ll add some more details (source code, jsp’s, required jar files etc.) as and when it occurs to me.

Micro-Interfaces

Untangling the Gordian Knot. Currently working on a project to untangle a hairball project. Its quite tempting to cut the Gordian Knot, but we… [development]

Interfaces are my friend in this situation. I have found it really useful to extract a single method on the bloated object I’m trying to break up into an interface, and substituting a reference to the interface in the calling code wherever possible, repeating for each method, initially by defining one interface per method, and occasionally consolidating the interfaces where I find that several of them are passed around together. It does mean that for really blob-like objects, at about the halfway stage I find myself with humourous constructors like:-


MyThing thing = new MyThing(this, this, this, this, this);

Where ‘this’ is some bloated object that now implements 5 distinct interfaces, and the target class has been refactored to work through the interfaces. Its so obviously wrong that sheer embarrassment forces you to keep refactoring until its all clean. Writing tests gets really easy too. Its easy to make the TestCase implement an interface and pass itself to the object under test (self-shunt pattern) when the interface only declares one method!

Aspects == Indirection ^2

Jumping back on the aspects bandwagon (trying to explain something often helps
me to understand it):

Indirection, aka abstraction: You call a method on an interface, and the
recipient is determined at runtime, and may be at the end of several ‘middlemen’
who simply pass the message along. What AOP does for you is allow you to
dynamically compose a whole method call chain using reusable interceptors. So
calling setFoo() on something that appears to be a simple bean can actually take
a quick detour to your validation interceptor to check the syntax, then visit
the persistence interceptor, telling it that the field is dirty, before
returning. This is nothing that can’t already be done without AOP, but AOP (ie.
interceptors & extensions) appears to be much more flexible and reusable. Being
able to define your interceptor stack in a descriptor or programmatically means
you can substantially alter the behaviour of bits of your application while its
running, and the calling code still sees a simple ‘setFoo’ bean like interface.
And the possibilities for code reuse look huge.

Of course, I could be entirely wrong – I’m still trying to wrap my brain around
the concept.

WebWorking

Webwork+XDoclet 1.2 beta+ANT+Resin == Rapid Prototyping City

This is somewhat sketchy on the details, but I wanted to get it out there while it was fresh in my mind.

How to iteratively prototype a webapp:-

Get Webwork and import it into your project.

Slap together an ANT script that compiles your stuff and WARs it up, puts the web.xml file from webwork in WEB-INF and includes webwork.jar in your WEB-INF/lib folder. Add an extra line to copy your WAR to your servlet container’s webapps directory.

Build at least one class that extends ActionSupport. Override execute() to return Action.SUCCESS.

Put a class-level javadoc comment that looks something like this in it:


/**

* @webwork.action

*   name="myCoolAction"

*   input="myInput.jsp"

*   success="myCoolActionSuccess.jsp"

/*

Write a simple jsp called myInput.jsp with an input form along the lines of:-


FORM METHOD="POST" ACTION="myCoolAction.action"

Write a quick success.jsp page with a ‘well done’ or similar message.

Get XDoclet 1.2 beta. Stick the jars in Ant’s classpath. Add a target that look like this:-


<target name="xdoclet" depends="init"

<taskdef

name="webdoclet"

classname="xdoclet.modules.web.WebDocletTask"

classpathref="class.path"

/>


<webdoclet

destdir="${build}/src"

mergedir="parent-fake-to-debug"

excludedtags="@version,@author,@todo"

addedtags="@xdoclet-generated at ${TODAY}, XDoclet,@version ${version}"

verbose="false"

>


<fileset dir="${src.java}">

<include name="**/*Servlet.java"/>

<include name="**/*Filter.java"/>

<include name="**/*Tag.java"/>

<include name="**/*Action.java"/>

</fileset>

<webWorkConfigProperties destDir="${webinf.classes}"/>

</webdoclet>

</target>

Include the target into your default build, just before the compilation step.

Run ANT. Wait for resin to reload your webapp.

Open /yourWebapp/myInput.jsp. Submit it. See the success.jsp page. Modify your Action class’s execute() method to actually do something, like check for the right name/value pairs. Make it return Action.INPUT to go round again, Action.SUCCESS to succeed and go to success.jsp, Action.ERROR to report an error etc.

Repeat.

More details when I have time.

Engage google before opening mouth

it’s actually really simple.

Web-the_simplest_thing_that_can_possibly-Work. I get WebWork. Finally. For some reason I’ve had a mental block on it up until now. Every time I sat down to explore it something came up, or I got bored. Finally cracked it this afternoon. Turns it I was expecting something complex, and it’s actually really simple. This appeared to cause me as much (or more) mental discontinuity as when I’m expecting something to be trivial, and it turns out to be much more complex. WW really is very simple, but it lacks an ‘idiots guide’ which would have been very helpful to me. I’ll see if I can retrace my steps and post my experiences up sometime. [Pushing the envelope]

Great! A WW idiots guide would be fantastic. Did you read Joseph Ottinger’s tutorial? Maybe that would be a good starting point to collaborate on?

[rebelutionary]

Doh! No I didn’t know about Joseph’s tutorial, I must have skimmed over the post where you mentioned it. That would have made life much easier 🙂

I find this kind of blow-by-blow guide to be an excellent ‘kickstart’ when using a new tool or framework. It helps me get my mind around the paradigm of the tool being used. I wish every new technology had one of these. For anyone else like me who missed Mike’s link, the guide can be found here:-

http://enigmastation.com/~joeo/webwork.html

Ambivalence

I hate starting projects. Writing ANT scripts, setting up the directory structure, configuring the IDE settings, putting all the library jars in the right place etc. I find it all immensely tedious.

I love starting projects. There’s no code written, you are full of ideas, with an infinite solution space to choose from. The journey lies ahead.

So to recap, I love hate love, have mixed feelings about starting projects.

Web-the_simplest_thing_that_can_possibly-Work

I get WebWork. Finally. For some reason I’ve had a mental block on it up until now. Every time I sat down to explore it something came up, or I got bored. Finally cracked it this afternoon. Turns it I was expecting something complex, and it’s actually really simple. This appeared to cause me as much (or more) mental discontinuity as when I’m expecting something to be trivial, and it turns out to be much more complex.

WW really is very simple, but it lacks an ‘idiots guide’ which would have been very helpful to me. I’ll see if I can retrace my steps and post my experiences up sometime.

Revisionism

Found this rather interesting example of slogan reuse while browsing Netscape’s homepage on the wayback machine. Right at the bottom of the page, a reference to ‘Netscape ONE, the Open Network Environment’. Fast forward 6 years and a joint venture or so later, and we have Sun ONE: Open Net Environment. Wow, they have been planning this for a long time, apparently.

HTTP Hangups

Conditional Get Update. Various news aggregators are leaping on the conditional get bandwagon. (108 Words) [The Fishbowl]

Its somewhat ironic that all this effort is suddenly being devoted to make aggregators only perform full GETs when they are needed, when as anyone who’s ever developed a public facing stateful web-app knows, its usually a knock-down drag-out fight to prevent misconfigured proxy servers from caching all your pages (and cookies, some of them) for all eternity and breaking your app in a variety of interesting and humorous ways.