Archive for June, 2003

The Blojsom Calendar Plugin

I noticed today that my calendar was only showing the posts that were on
the front page of my blog. After a little investigation I figured out that this was because
I had the blojsom limiter plugin
configured before the blojsom calendar
plugin in my plugin.properties file. Hopefully this will get indexed so if anyone
else has the same problem this will help them some.

My html display chain now looks like:

html.blojsom-plugin-chain=calendar-filter, comment, trackback, \ sendemail, calendar-gui, limiter, simple-search, referer-log

Comments

Garbage Collection

I had a discussion with a friend today about Garbage Collection. He has quite
a “messy room” problem - his bedroom is so full of stuff that he couldn't close the
door for a few months, and spend 3 (?) weeks sleeping on the couch because there was too much
stuff on the bed.

We decided that his problem was that his garbage collector isn't doing
minor collections of the
new object eligable for GC, so they just lay around and wait for a major collection.
However, there is so much garbage waiting for that major collection that the
Mark-compact collection algorithm used there is continually fighting a loosing battle
against the garbage.

We also decided that leaving stuff at a friends (or parents) house is actually a memory
leak.

How am I going so far, Superman? ;-)

Also, does this code looks familiar to anyone else:

public class Superman implements Runnable { private boolean doneEnoughWork = false; private boolean feelingSmartToday = false; public void run() { while (!doneEnoughWork) { work(); } if (feelingSmartToday) { // set the alarm object to interrupt this thread in about // 8 hours AlarmClock.set(Thread.currentThread()); } else { // BodyClock is an unstable time keeping // mechanism and should be treated with caution. // It is designed for use on resource constrained VMs // such as the PrimativeMan embedded VM and the // WeekendVM // // It may interrupt the thread passed in roughly // 8 hours, plus or minus and hour or two. BodyClock.pleaseWakeMeUp(Thread.currentThread()); } try { Thread.currentThread.sleep() } catch (InterruptedException e) { getUpAndGoToWork(); } } }

Comments

Maven and CVS Connundrum

So I've fixed my CVS/Maven issues. It turns out that you need to specify a CVS repository like:

scm:cvs:pserver:anonymous@cvs.sourceforge.net:/cvsroot:classifier4j

rather than

scm:cvs:pserver:anonymous@cvs.sourceforge.net:/cvsroot/classifier4j

Apparently, this is assumed knowledge or something, or is just a CVSism.

I was basing my setting on the sourceforge documentation:

cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/classifier4j login cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/classifier4j comodulename

The SF documentation is usually
quite good…. Oh well… the joys of different development environments.

Comments

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.

Comments

JAdvice - A Pointer?

JAdvice is an AOP framework written in Java
using Javassist.

The only docs I can find are the javadocs (which
are actually quite good). I'd love to give
it a try
, but can someone point me at an example of its usage? If this is a “you need to be a real man and read the
code” I'm usually up for that too, but I just want to be sure I'm not missing anything.

Comments

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

Comments

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).

Comments

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

Comments

List of Java AOP Frameworks

I'm looking for a list of Java AOP Frameworks that are publically available. I know about:

Are there any more?

Comments

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:

Comments