All posts by Nick Lothian

Classifier4J 0.2 Released

I did my first formal release (v0.2) of Classifier4J (Bayesian text classification)
via SourceForge a couple of days ago. It's an interesting experience – I swear I've spend more time wrestling with Maven and CVS than
I have actually writing code. At the moment I have a very interesting error when I have
the CVS repository in my project.xml:

maven-checkstyle-plugin:report: [echo] Generating the Change Log... maven-changelog-plugin:report: [echo] Generating the changelog report BUILD FAILED null:37:50: null:56:15: null Total time: 11 seconds

I don't have a clue what that means, so I've commented it out at the moment. Maybe I need a command line CVS client? I'll
try that after I post this.

My future plans for Classifier4J include:

  • Include some demos
  • Making it use JISP instead of a JDBC datasource
  • Everything in my task list
  • Other, non Bayesian implementations.

All in all, I'm not overly happy with this release, but I wanted to get myself moving on it again.

Funny Story from Media Watch Tonight

This is (mostly) for the Aussies amoung you. Media Watch had a
story tonight
on how online polls run by newspapers are being rigged. Apparently this is quite a big deal – questions
are being asked in senete hearings. Here's a quote:

The NSW north coast paper had asked if the Liberals should field a candidate against the local national party member at the next state election. The Nats are desperate to avoid such three-corner contests. We'll let Labor Senator John Faulkner take up the story. There were 44 votes on his poll at 8 pm on the Monday night after it had been started and the web address was being given and then it got bombarded with hundreds of hits primarily from two locations. And this is the issue I want to raise with you: one of those locations is linked to the Dept of - according to news reports - was linked to the Department of Foreign Affairs and Trade. - Senate hearing, 2 June 2003 Watch video >> The hapless DFAT official being grilled confirmed that a staffer of the Minister for Trade - that's the National Party's Mark Vaile - was responsible for casting the votes - 337 "No" votes it turns out - from a computer in the minister's parliamentary office. Someone else - never identified - then started casting hundreds of "Yes" votes in favour of the Libs..

From http://www.abc.net.au/mediawatch/transcripts/s886149.htm

On Display Layers

When two people
who's work
I respect say almost the same thing within a couple of days of each other, I take notice.

Howard says:

there's a prevalent myth that a single web application should cater to a desktop client,
a palmtop client and a cell phone client in exactly the same way.

Ted says:

I'm firmly convinced that trying to build a single user interface code base that knows how to render
itself to multiple channels is not only a waste of developers' time, but a waste of users' time, too.
Inevitably, you want to do something (or, more likely, the users want you to do something) that needs to
take advantage of the unique, value-added features of that particular channel, and suddenly you're in the
world of #ifdef-ed or special-case coding.
This is also where you start down the slippery slope of tangled concerns and spaghetti code.

I think they are right. I've never written an application that uses the same display layer to target separate
devices or display modes, but I have written apps
that have multiple client types connecting to the middle-tier layer. We continually see issues even with this
separation of data – the thin client needs “just a bit” more done, or the thick client sends the data “just a little bit”
differently.

Surely similar issues happen when the display layer trys to cater for more than one device? (I'm not interested in
theoretical arguments here – I understand perfectly well the attraction of writing code one. What I'd like to hear about
is an application where it has been done successfully).

A Journey through three Aspect Oriented Frameworks

Earlier this year the Java blog world got very excited about Aspect Oriented Programming (AOP) and Java based frameworks
to enable it. At the time the only AOF mature enough to be used was AspectJ, but now there are at least three other frameworks
around designed to make AOP doable. I'm interested in this because when the idea first came up I implemented and threw-away
my own framework, because I wanted to see what others were doing.

With the recent release of the JBoss 4 Devlopers Release, I decided it was time to have a play. This is my initial
impressions after attempting to do the same thing in each framework. I didn't compare AspectJ, although I may at a later date.

The three frameworks I tried were AspectWerkz, JBoss 4 AOP and Nanning. I attempted to implement a program that would
use a Mixin to output “Hello World” and would trace calls to the helloWorld method on the Mixin. While I
agree this is a pretty basic program, I hoped it would let me understand how each framework implemented
each of the four main principles of AOP
:

  • Interception (Advice): The tracing is done using an Interceptor (aka Advice).
  • Introduction: The output is done using an Introduction (aka Mixin).
  • Inspection: The interceptor works out what method is being called. It doesn't use any meta data at this stage, though.
  • Modularization: The “object” that is run is composed of a number of “things” – the Mixin and the Interceptor, each of which is a standalone module.

Overview

Probably the most surprising thing to me is how similar all three systems are.
All can use XML descriptors to setup the Aspects, and the syntax was quite similar, too.
All had the same requirements to use a Mixin – it should be a Plain Old Java Object (POJO) that implements an interface.
Infact, all frameworks let me use exactly the same code for the Mixins:

IHelloWorld.java


package example;

public interface IHelloWorld {
	public void helloWorld();
}
	

HelloWorldImpl.java


package example;

public class HelloWorldImpl implements IHelloWorld {
	public void helloWorld() {
		System.out.println( "Hello World!");
	}

}
	

Both AspectWerkz and JBoss AOP had “launcher frameworks” that allow use from the command line. AspectWerkz
provided a batch file (and shell script) that would setup the classpath and run a program through AspectWerkz.
Unlike Nanning and JBoss AOP, it requires a separate “weave” step after compilation if Mixins are used, and this
was also done from the command line:


src>java org.codehaus.aspectwerkz.metadata.SourceFileMetaDataCompiler /
		aspectwerks.xml . C:\java\aof\mycode\AspectWerkz\meta

compiling weave model...
weave model for classes in . have been compiled to C:\java\aof\mycode\AspectWerkz\meta

bin>aspectwerkz -Daspectwerkz.metadata.dir=C:\java\aof\mycode\AspectWerkz\meta /
		example.Pojo

JBoss AOP requires its dependancies to be added to the classpath manually, and then to set the system ClassLoader
when a Java program is run:


bin>java -Djava.system.class.loader=org.jboss.aop.standalone.SystemClassLoader example.Pojo

For both these systems, I was able to use the same base object (which I added my Mixin to):


package example;

public class Pojo {
	public static void main(String[] args) {
		Pojo pojo = new Pojo();
		((IHelloWorld)pojo).helloWorld();
	}
}

Nanning required setup code to be run in order to setup the Aspect System. This was fairly trivial, but made the
code not quite as neat as the other two systems. I also created an IPojo interface for the Pojo object to implement.
(This wasn't strictly required, but if I didn't make it do that the code looks like I'm just creating an
implementation of the IHelloWorld interface, not another object with a IHelloWorld mixin).


package example;

import java.io.IOException;

import com.tirsen.nanning.AspectInstance;
import com.tirsen.nanning.Aspects;
import com.tirsen.nanning.config.AspectSystem;
import com.tirsen.nanning.xml.AspectSystemParser;

public class Pojo implements IPojo {
	public static void main(String[] args) throws IOException  {
		// initialize Nanning
		AspectSystemParser aspectSystemParser = new AspectSystemParser();
		// load my config file
		AspectSystem aspectSystem = aspectSystemParser.parse(
						Pojo.class.getResource("nanning.xml"));

		// create the Aspect
		IPojo o = (IPojo) aspectSystem.newInstance(IPojo.class);
		AspectInstance instance = Aspects.getAspectInstance(o);

		// get the IHelloWorld interface from the aspect
		IHelloWorld helloWorld = (IHelloWorld) instance.getProxy();
		// call the method
		helloWorld.helloWorld();
	}
}

Configuration

All three frameworks can use an XML file for configuration. For JBoss AOP it is almost a requirement – there is very
little documentation for not using one (although it is possible, as JBoss 4.0 uses JMX for configuration). AspectWerkz may be
configured in code or via the XML file. Nanning can use an XML file for configuration, but most of the
documentation is for configuring it in Java.

Of the three, I found JBoss AOP the easiest to get to work. AspectWerkz confused me with the difference between
advices-def and advice-def (I only just worked this out), and while Nanning had a clean XML syntax, it took some time to
work out how much I could do in XML and how much I needed to do in code.

If you look closely at the configuration files you will notice that there are differences in functionality between
these configurations – in particular, the Pointcut the interceptors are applied on is specified quite differently.
AspeckWerkz uses a simple regular expression like syntax for matching classes and methods, JBoss uses JDK 1.4 RegExp
to match classes (I am unsure how to filter based on method names?). I couldn't work out exactly how rich Nanning's
pointcut specifications are. JBoss can intecept on Constructors, Methods, and Field access, AspectWerkz on Method and Fields
(I am unclear about constructors) while Nanning intercepts on Method invocation (again, I am unclear about constructors).

AspectWerkz:


<?xml version="1.0"?>

<aspectwerkz>
    <introduction-def name="helloworld"
			interface="example.IHelloWorld"
			implementation="example.HelloWorldImpl"
			deployment-model="perInstance"/>
    <advice-def name="tracing"
	        class="example.TracingAdvice"
	        deployment-model="perJVM"/>

    <advices-def name="tracer">
        <advice-ref name="tracing"/>
    </advices-def>

   <aspect name="Introduction">
		<pointcut-def name="pc" type="method"
			pattern="void example.*.helloWorld()"/>
		<advice pointcut="pc">
			<advices-ref name="tracer"/>
		</advice>
        <introduction class="example.Pojo">
            <introduction-ref name="helloworld"/>
        </introduction>
    </aspect>
</aspectwerkz>

JBoss AOP:


<?xml version="1.0" ?>
<aop>
	<introduction-pointcut class="example.Pojo">
		<mixin>
			<interfaces>
				example.IHelloWorld
			</interfaces>
			<class>example.HelloWorldImpl</class>
			<construction>new example.HelloWorldImpl()</construction>
		</mixin>
	</introduction-pointcut>

	<interceptor-pointcut class="example.Pojo" methodFilter="MEMBER"
							constructorFilter="NONE"
                            fieldFilter="NONE">
		<interceptors>
			<interceptor class="example.TracingInterceptor" />
		</interceptors>
	</interceptor-pointcut>
</aop>

Nanning:


<?xml version="1.0"?>

<aspect-system>
	<class name="example.IPojo">
		<interceptor class="example.TracingInterceptor" scope="singleton" />
		<mixin interface="example.IHelloWorld" target="example.HelloWorldImpl" />
	</class>
</aspect-system>

Output

The output of the tracing interceptor was fairly similar for each framework.

AspectWerkz:


Entering method: public void example.Pojo.___originalMethod$helloWorld$1()
Entering method: public void example.HelloWorldImpl.___originalMethod$helloWorld$1()
Hello World!
Leaving method: public void example.HelloWorldImpl.___originalMethod$helloWorld$1()
Leaving method: public void example.Pojo.___originalMethod$helloWorld$1()

JBoss AOP:


Entering public void example.Pojo.helloWorld()
Hello World!
Leaving public void example.Pojo.helloWorld()

Nanning:


Entering method: public abstract void example.IHelloWorld.helloWorld()
Hello World!
Leaving method: public abstract void example.IHelloWorld.helloWorld()

Notice the different stack traces on the tracing output? This provides a pointer to how each
system is implemented. AspectWerkz and JBoss AOP use ByteCode manipulation, while Nanning uses
dynamic proxies.

Framework Summary

AspectWerkz
Version: 0.6.3
Licence: LGPL
Site: http://aspectwerkz.codehaus.org/
Doc: http://aspectwerkz.codehaus.org/documentation.html
Download: http://aspectwerkz.codehaus.org/releases.html
Blogs: http://blogs.codehaus.org/projects/aspectwerkz/
http://blogs.codehaus.org/people/jboner/
AOP Style: Byte code modification at runtime using BCEL. A post compilation “Weave” step is required in some
configurations.
Build: Both Ant and Maven build files are included. The Ant build failed because it was
set to use jikes as the compiler. Once I removed that, it compiled. The Maven build
was successful, but maven all copied all docs to c:\tools\Apache2\htdocs after
creating that directory.
Dependancies: bcel-5.0.jar,
jmangler-core-3.0.1.jar,
trove-1.0.2.jar,
dom4j-1.4.jar,
qdox-1.2.jar,
commons-jexl-1.0-beta-2.jar,
concurrent-1.3.1.jar,
jisp-2.0.1.jar,
ant-1.5.2.jar,
junit-3.8.1.jar
JBoss AOP Framework
Version: jboss-aop-DR1
Licence: LGPL
Site: http://www.jboss.org/
Doc: http://www.jboss.org/index.html?module=html&op=userdisplay&id=developers/projects/jboss/aop
Download: http://www.jboss.org/index.html?module=html&op=userdisplay&id=downloads
AOP Style: Byte code modification at runtime using Javassit.
Build: No buildfile was included. I didn't attempt to build manually.
Dependancies: javassist.jar,
jboss-aop.jar,
jboss-common.jar
Nanning
Version: 0.6
Licence: LGPL
Site: http://nanning.sourceforge.net/
Doc: http://nanning.snipsnap.org/space/start
Download: http://sourceforge.net/project/showfiles.php?group_id=64968
Blog: http://www.freeroller.net/page/tirsen

AOP Style: Use of interfaces and dynamic proxies
Build: Only Maven build file included. Maven executed successfully, but maven site:generate failed.
Dependancies: ant-1.5.2.jar,
commons-beanutils-1.5.jar,
commons-collections-2.1.jar,
commons-digester-1.3.jar,
commons-jelly-20030310.073407.jar,
commons-lang-1.0.jar,
commons-logging-1.0.2.jar,
concurrent-1.3.2.jar,
dom4j-1.4-dev-8.jar,
junit-3.8.1.jar,
log4j-1.2.8.jar,
nanning-0.6.jar,
ognl-2.3.2.jar,
prevayler-2.00.000dev.jar,
qdox-1.1.jar

Some tips for customising Maven built websites

Struggling to work out how to customise your Maven built website? Here's
a few thing I've figured out. All this is actually documented on the Maven site, but I found it a little
hard to find.

The first thing I wanted to do was include some custom pages on my site. To do this, you need to create an
“xdocs” directory in the root of your project, and put the files you want to end up on your site in there. Anything
except .xml files will be copied to the target/docs directory, which allows you to use images or plain HTML files. If
you want your pages to be generated in the same style as the rest of the Maven generated pages, you need to use a format
called xdocs. The xdocs format is (somewhat) documented on
the Jakarta site
(ie, there is an example file). In my experience so far, it is basically a cut down, xmlised version
of html.

Now you can run maven site:generate and your new page will be generated. However, it will not show up on
the menu yet. To do that you will need to create a file called navigation.xml in your xdocs directory. The format
for this file is documented on the Maven site. I needed to leave out the
encoding from the example for it to work for me, however.

navigation.xml also controls what Maven calls the “navigation bar”. This is the bar across the top of the page,
that typically has a link to the Maven site at the top right side. To modify that, create a “links” section inside the body
of navigation.xml.

Here's an example navigation.xml:



<?xml version="1.0"?>
<project name="${project}">
	<title>Classifier4J</title>
	<body>
		<links>
			<item name="Sourceforge"  href="http://sourceforge.net/" />
			<item name="Blog"  href="http://www.mackmo.com/nick/blog/"/>
		</links>
		<menu>
			<item name="Home" href="index.html" >
				<item name="Usage" href="usage.html" />
				<item name="Applications" href="applications.html" />
				<item name="Download" href="download.html" />
			</item>
		</menu>
		<!-- footer will be placed above the (c) -->
		<footer>
			<a href="http://sourceforge.net/projects/classifier4j">
			<img src="http://sourceforge.net/sflogo.php?group_id=72748"
			border="0" alt="sf logo"/>
			</a>
		</footer>
	</body>
</project>


Now I'm trying to figure out how to customise the Checkstyle plug-in settings…

Some links I found useful:

An Ode to JDK1.5

Tiger, Tiger burning bright
Like a geek who works all night
What new-fangled bit or byte
Could ease the hacker's weary plight?

To the most despised collections' cast
We'll bid a fond farewell at last
With generics' burning spear
The need for cast will disappear

While Iterators have their uses
They sometimes strangle us like nooses
With enhanced-for's deadly ray
Iterator's kept at bay

When from the collections ints are drawn
Wrapper classes make us mourn
When Tiger comes, we'll shed no tears
We'll autobox them in the ears

The int-enum will soon be gone
Like a foe we've known too long.
With typesafe-enum's mighty power
Our foe will bother us no more

And from the constant interface
We shall inherit no disgrace
With static import at our side
Our joy will be unqualified

As for noble metadata
I'll have to sing its praises later
Its uses are so numerous
To give their due, I'd miss the bus

Tiger, Tiger burning bright
Like a geek who works all night
What new-fangled bit or byte
Could ease the hacker's weary plight?

From http://www.theserverside.com/resources/articles/JavaOneDayThree_03/article.html

Tapestry

I've finally had a chance to look at Tapestry.
Wow! That is a pretty impressive bit of work. Firstly, it has a nice demo that works straight out of the
box (although you need to run an ant script to deploy it – I'm not sure why it doesn't just ship with a
deployable WAR). Secondly, the demo has lot of stuff that I've never seen other frameworks supply (eg, the property
inspector). It gives you the impression that it really is a lot more advanced than anything else out there.

It's hard to see what Tapestry competes with. It's more than just a MVC (struts/webwork etc) framework –
I guess JavaServerFaces+MVC framework is in the same area. Having done a reasonable amount of tag library development
myself, though, I am yet to be convinced by JavaServerFaces.

If Tapestry came with a GUI development tool then it would match ASP.NET+Visual Studio quite well.
Spindle – an Eclipse plugin – is available, but it doesn't
support Tapestry v3 yet.