« January 2006 | Main | March 2006 »

February 13, 2006

Remembering Ragin Miller

Ragin Miller Westerlund

My roommate, John Ragin Miller, a man of acid wit and cynical humor, died one year ago today. It was Monday, February 14, 2005. Ragin, whom I sometimes called "Johnny Ray-Gun" was 30 years old when he died of, among other things, complications from his long battle with diabetes. Those other things include untreated acute and chronic depression, poverty, frequent alchohol use, and a street "counterculture" completely devoid of the power to instill hope and promise to a young man in dire straits.

Those who knew him will agree that he died of a broken heart. When a man's heart breaks, romantic love is only the first thing to go. The weight of debt, poverty, sickness and anger can drive one beyond dispair, and break the very will that makes us human. I believe that Ragin expressed his will in his spirited and blistering wit, but that it failed in the end to keep him afloat.

Ragin, despite his many troubles, was a talented actor and critic, with a sense of irony that far outstrips that of most people. Moreover, he possessed an ability to acknowledge and directly confront the uglier aspects of human life. I count my conversations with him during his lucid moments among the most rewarding of my life.

Ragin was a terror in the kitchen. He was a gifted cook, and he employed his encyclopaedic memory to excellent use in his distinctly southern cuisine. His tyrannical manners in the kitchen only contributed to his charm. He was a proud American from beneath the Mason-Dixon line, a fact he never let his "Damned Yankee" roommates forget.

I can't say enough about Ragin. He remains unforgettable. Today, one year after his death, I wish to remember him and send my warm regards to his mother and father.

Requiem Eternitum, Ragin.

Ragin Miller Westerlund

February 11, 2006

Critique of XpTrackerPlugin for TWiki

I've been working on a Sample Iteration of an eXtreme Programming project, using the XpTrackerPlugin. This tool takes me close enough to what I need to leave me very disappointed. I don't wish to obey the old maxim not to look a gift horse in the mouth. Instead, I'll give what I think is a fair and useful critique of the plugin.

  1. Obey XHTML. The XHTML standard should be rigorously obeyed at every step, so that it doesn't break other skins. I tried to use the program with the Nat skin, but it breaks the Nat skin on the iteration pages, probably because of failures to close block-level elements like div or table tags. There might also be failures in the Nat skin, but I haven't found them anywhere else.
  2. Do not require Wiki Words for topic names. This precludes you from using names for iterations such as "Snapshot01", and makes the tool nearly unusable. Wiki words are for the weak.
  3. Mind your table widths. The default tables wander waaaaay off my screen, again making the software nearly unusable. I have to shrink my font to see and edit table contents, and even then I can't see it that well.
  4. Never hard-code colors into your HTML. You should always use a .css style for this, so that the user can override it. The default colors practically ensure a headache, unless you have partial ocular monochromatism, in which case you'll be completely lost and without hope. The alternate option to define colors in the WebPreferences is a nice touch--use that or CSS exclusively.
  5. CSS: Use more of it. Every block level, at the very least, should be stylable. That means naming classes for these elements. Use a central style sheet that people can edit for their personal tastes.

I might add more as I think of it. For now, these are the chief improvements I can recommend for this plugin. If I manage to implement any of these customizations, I'll be sure to give them back to the community. Although much of the trouble I'm having evaporates when using the Pattern skin, I think these forms and tables should all be more stylable. Please, don't anyone take this critique as my failure to appreciate Rafael's contribution or stemming from any delusions that I'm somehow entitled to more for nothing.

Summary

The XpTrackerPlugin works well with the pattern skin. There are some quirks in the layout and organization of the data, the plugin forces you to use WikiWords for topic names, which preclude the use of numbers. So, for an iteration name, "alpha_01" is illegal, as are "Alpha01" and "Alpha-01". The part that requires this needs to be fixed and all of the links on the different templates need to be rewritten to link non-wiki-word topic names. It's a tremendous start, to be sure, but the project could use a good spitshine before the next release. Out of five stars, I give it three and a half stars. I commend Rafael for his prompt user support and for eating his own dog food.

February 10, 2006

Specifying Instances of Multiple Types in PicoContainer

Having satisfied myself yesterday on the question of whether or not PicoContainer can pick specific object instances of the same type out of the container while building other components, I now turn to the question of whether it can perform with the same precision while working with objects of differing type. I am happy to find that it is indeed possible and simple.

Let's say that the example I've been using so far, involving the Juice object, has an optional third constructor, which accepts two Fruit objects and a Cup object. I need to distinguish between specific instances of Fruit, and add a different type as the third constructor parameter. Here's how you accomplish that in PicoContainer.

    public void testMultiplePicoParamTypes() throws Exception {
        addFruit("lemon");
        addFruit("lime");
        addFruit("bubble", "tapioca");
        c.registerComponentInstance(
                "teacup", 
                new Cup("teacup"));

        c.registerComponentImplementation(
                "lemonbubbletea",
                Juice.class, 
                new Parameter[]{
                    new BasicComponentParameter("lemon"),
                    new BasicComponentParameter("bubble"),
                    new BasicComponentParameter("teacup")});

        Juice lemonbubbletea = getJuice("lemonbubbletea");

        Assert.assertEquals(
                "lemon", 
                lemonbubbletea.getType());

        Assert.assertEquals(
                "tapioca", 
                lemonbubbletea.getSecondIngredient());

        Assert.assertEquals(
                "teacup", 
                lemonbubbletea.getCupType());

        claimVictory();
    }

This permits one to keep a broad level of abstraction for the object instances, while maintaining specifically how they are assigned to be used by another object later on. Soon, I will illustrate why this is useful and in fact crucial to certain types of programming.

February 09, 2006

Multiple Constructor Parameters of the Same Type in PicoContainer

One of the most important features in an Inversion of Control container for me has been the ability to bootstrap components from the container that have multiple constructor parameters of the same type, without running into amiguity problems. I want to be able to direct which specific component gets loaded first, which specific instance loads second, and so on. Some contend that my need to do this points to bad design, but I don't particularly care. I know why I need to do it this way and no other way.

Besides, PicoContainer can do this easily, so obviously I'm not the first to require this type of feature. Here's a code snippet that shows how it's done.

    public void testMultiplePicoParams() throws Exception {
        c.registerComponentInstance(
                "lemon", new Fruit("lemon"));
        c.registerComponentInstance(
                "lime", new Fruit("lime"));
        c.registerComponentInstance(
                "bubble", new Fruit("tapioca"));

        c.registerComponentImplementation("lemonbubble",
                Juice.class, new Parameter[] {
                    new BasicComponentParameter("lemon"),
                    new BasicComponentParameter("bubble")});

        Juice lemonbubble = getJuice("lemonbubble");

        Assert.assertEquals(
                "lemon", lemonbubble.getType());
        Assert.assertEquals(
                "tapioca", lemonbubble.getSecondIngredient());

        System.out.println("w00t!  Pico can properly " +
                "create complex component instances.");
    }

I ran this test today and it worked perfectly as I expected. The container can create objects with as many or few objects of whichever type I need in the constructor. It Just Works (TM).

Did I mention yet how happy I am with PicoContainer? Inversion of Control exactly how it should be.

February 08, 2006

Smooth moves with PicoContainer

After all these years, I still love PicoContainer. I can't help it. It does exactly what I need it to do, and no more. About six months ago I found out that I could use PicoContainer to build components at runtime from specific instances of other objects in the container. For example, you ask the container for a type of Juice that is made from a specific type of Fruit in your container, based on a name you've previously given that specific instance of Fruit. This allows you the twin comforts of abstraction in your class implementation and precision in your runtime targeting of those objects in the container. It's the best of both worlds.

/**
 * COMMERCIAL OBJECT RELATIONAL MAPPING  (CORM) PROJECT

 * This document is Copyright (C) 2004-2006 
 * Alexander Saint Croix.  All rights reserved.
 *
 * THE CONTENTS OF THIS FILE MAY BE USED 
 * UNDER THE TERMS OF THE
 * ACADEMIC FREE LICENSE, VERSION 2.1.
 *
 * See http://opensource.org/licenses/afl-2.1.php 
 * for details.
 */
package org.eremite.examples;

import junit.framework.TestCase;
import junit.framework.Assert;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.Parameter;
import org.picocontainer.defaults.DefaultPicoContainer;
import org.picocontainer.defaults.BasicComponentParameter;

public class PicoContainerTest extends TestCase {
    private MutablePicoContainer c;

    public void setUp() throws Exception { 
        super.setUp();
        c = new DefaultPicoContainer();
    }
    
    public void tearDown() throws Exception {
        super.tearDown();
    }
    
    
    public void testPicoBehavior() throws Exception {
        c.registerComponentInstance(
                "lemon", new Fruit("lemon"));
        c.registerComponentInstance(
                "lime", new Fruit("lime"));
        c.registerComponentInstance(
                "bubble", new Fruit("tapioca"));
        
        c.registerComponentImplementation("lemonjuice", 
                Juice.class, new Parameter[] {
                    new BasicComponentParameter("lemon")});
        c.registerComponentImplementation("limejuice", 
                Juice.class, new Parameter[] {
                    new BasicComponentParameter("lime")});
        c.registerComponentImplementation("bubbletea", 
                Juice.class, new Parameter[] {
                    new BasicComponentParameter("bubble")});

        Juice lemonade = getJuice("lemonjuice");
        Juice limeade = getJuice("limejuice");
        Juice bubbletea = getJuice("bubbletea");

        Assert.assertEquals("lemon", lemonade.getType());
        Assert.assertEquals("lime", limeade.getType());
        Assert.assertEquals("tapioca", bubbletea.getType());
        
        System.out.println("w00t!  Pico works.");
    }
    
    private Juice getJuice(String s) {
        return (Juice) c.getComponentInstance(s);
    }
}

What happens in the code above is great. First, I feed a handful of Fruit components into the container, giving each of them names and distinguishing them from each other by a String. Then, I register a handful of Juice components in the container, each according to a different type of Fruit.

Later on, when I need some Juice, I can get it by name, and the type of Fruit that it contains is also pulled from the container. This allows me to feed abstract concepts of objects into a container, and ask for a fully constructed object that contains other objects in the container.

It's great Inversion of Control. Elegant, simple, lightweight. Gotta love Pico.

Now, a further question I'm wondering is whether I could make a JuiceMix object out of two types of Juice, and be able to ensure that the first one is a lemon and the second is a lime. Both objects are Fruit--can the container recognize the difference, or is it too ambiguous? If I could do this, it'd allow me to do very complex action processing in a declarative runtime environment in response to changing state conditions. It'd be very powerful.

PicoContainer 1.1, at only 75Kb, is a much sweeter deal for raw IoC than Spring at 32Mb. There used to be a SpringContainer available, but it required a lot of XML configuration and overhead that I didn't want to trouble myself with at the time, when I can get what I need from PicoContainer. I've recently heard of something cleverly dubbed "femtocontainer", which uses java.beans.XMLDecoder to accomplish much of what Spring does. Now that's an interesting idea that I'll look into more.

February 03, 2006

Is my XpTrackerPlugin Installation "Tainted"?

I'm still working on actually getting the XpTrackerPlugin to work with my TWiki installation. Now that I've gotten the plugin to install, I'm on to some runtime errors, two of which I've posted below.

First, there's the missing function reference:

TWiki detected an internal error
please check your TWiki logs and
webserver logs for more information.
Undefined subroutine &TWiki::isWikiName called

That's on line 631 of the XpTrackerPlugin.pm file. I contacted Rafael Alvarez about it, and he made a quick update to the SVN repository, which I downloaded and installed. Now I get a different error:

TWiki detected an internal error - please
check your TWiki logs and webserver logs
for more information.
Insecure dependency in open while running
with -T switch

This seems to indicate some kind of security or trust issue. I thought at first that this might be somehow related to these files being in their own Tracking web, and not integrated with another web, so I created a new web called "Obscure", which I'll use for quietly testing new features like this one. I was hoping that having it in another web would fix it--perhaps there was some permission problem? Unfortunately it did not. I've replied to Mr. Alvarez and I eagerly await his reply.

He said that he was going to update the code in SVN and conduct some more testing over the weekend. I'll be waiting anxiously for the results while he does. I'm really looking forward to using this for working on my software development projects. I also think it might prove useful for the UMWiki project, and the computer science department might find it very useful for running classroom software projects.

What would be great is if we could get some of the folks in Carlson School of Management working on Agile development projects with the folks in Computer Science, so that both sides learn good development methods. The question hinges on whether CSoM knows about Agile Development processes or not. I'm sure if the infrastructure is there for us to easily engage in Agile projects, then more people will give it a try.

Update, 2006-02-06

Eureka! The ever-diligent Rafael Alvarez has checked in a fully-functional revision to SVN. I've installed it on my server and it works as expected. Now I can turn my attention to improving the quality of the templates, fully integrating it with the NatSkinPlugin and working on my software.

I'd like to give a special thanks to Rafael Alvarez for his excellent attention to his users. He actually apologized to me for my trouble when his software didn't work--and it's free software! This is what makes Open Source so special to me--I've nothing but respect and admiration for the man. Thank you, Mr. Alvarez! You do great work.

Hopefully in the future I'll be able to help iron out these kinds of wrinkles in TWiki, instead of merely reporting them.

February 02, 2006

University Departmentality hinders the Wiki effort

I had a great conversation today with a wikiuser about how turf grabbing and secrecy could greatly hinder the collaborative benefits of the UMWiki project. The chat transcript follows.

[11:08 AM]<wikiuser>     morning alex. I've a twiki question if you've a moment
[11:51 AM]<alexander>     go right ahead
[11:52 AM]<wikiuser>     one sec...UMWikiAdmin may have my answer
[11:52 AM]<alexander>     k
[11:56 AM]<wikiuser>     hrm, she disappeared....my question was about using access control
[11:56 AM]<wikiuser>     I am working on the TopSecretOffice information
[11:56 AM]<wikiuser>     and importing the stuff from our wiki over there
[11:56 AM]<wikiuser>     and wanted restricted view on some of what is there
[11:56 AM]<alexander>     okay
[11:57 AM]<wikiuser>     and restricted edit on much
[11:57 AM]<alexander>     you can restrict view and edit in the WebPreferences topic for that web
[11:57 AM]<wikiuser>     the format for Set ALLOWTOPICCHANGE
[11:57 AM]<wikiuser>     entry required per page
[11:57 AM]<alexander>     The basic deal is that you need to create a Group for your users, and give them privs to view / change settings.
[11:57 AM]<wikiuser>     the group is created
[11:57 AM]<wikiuser>     UMWikiAdmin got me that
[11:58 AM]<alexander>     Hokay, so now you configure the Web Preferences. Lemme see if I can find something more specific.
[11:58 AM]<wikiuser>     okie
[11:58 AM]<wikiuser>     thanks
[11:59 AM]<alexander>     http://twiki.org/cgi-bin/view/TWiki/WebPreferences
[12:00 PM]<alexander>     that page has a set of User / Group permissions
[12:00 PM]<wikiuser>     okie
[12:00 PM]<wikiuser>     thanks
[12:00 PM]<alexander>     In order to set a preference you'll want to type " * Set PREFERENCE = whatever you like"
[12:00 PM]<wikiuser>     ok
[12:00 PM]<wikiuser>     and that is per page
[12:00 PM]<wikiuser>     ??
[12:01 PM]<alexander>     three spaces, asterix, space, then "Set ", name of pref, equals, name of value.
[12:01 PM]<alexander>     No, this version of TWiki we're using doesn't allow topic level preferences.
[12:01 PM]<alexander>     That feature is forthcoming.
[12:01 PM]<alexander>     A new version of TWiki was released today and we're evaluating it.
[12:01 PM]<wikiuser>     okie
[12:01 PM]<alexander>     So, it might be Real Soon Now
[12:02 PM]<wikiuser>     alirhgty
[12:02 PM]<wikiuser>     good to know
[12:02 PM]<alexander>     kp
[12:03 PM]<alexander>     All good?
[12:03 PM]<wikiuser>     I believe so...I had UMWikiAdmin install a syntax highlighting plugin and am trying to get that working...I may bug you if I am unsure of anything...thanks!
[12:03 PM]<alexander>     kp
[12:20 PM]<wikiuser>     two questions quick
[12:20 PM]<wikiuser>     https://wiki.umn.edu/twiki/bin/view/OurInternal/TopSecretOffice
[12:20 PM]<wikiuser>     the permissions are set wrong there
[12:20 PM]<wikiuser>     and I must be missing something as to how to specify
[12:21 PM]<alexander>     hrmm.
[12:21 PM]<alexander>     This isn't going to work.
[12:21 PM]<wikiuser>     alright
[12:21 PM]<alexander>     You're working inside of the OurInternal web
[12:21 PM]<wikiuser>     is it because it is in OurInternal
[12:21 PM]<alexander>     We can't do subwebs yet.
[12:21 PM]<wikiuser>     ok
[12:21 PM]<alexander>     That's in the next release.
[12:21 PM]<wikiuser>     got it now
[12:21 PM]<wikiuser>     no biggie
[12:22 PM]<alexander>     If you need a TopSecretStuffWeb, I'd write a request to the wiki folks and UMWikiAdmin could help set one up for you.
[12:22 PM]<alexander>     What sort of top secret stuff do you want to do in there?
[12:22 PM]<alexander>     If you had your own web (like OurInternal or TheDepartment has, for example), you could choose exactly who had view/write permissions for the web
[12:22 PM]<wikiuser>     well there is some information about hosts we connect to and information (e.g. TopSecretStuff) that we have access to that we'd prefer people didn't know we have access to
[12:23 PM]<alexander>     People inside of or outside of TheDepartment?
[12:23 PM]<wikiuser>     probably a bit of the former and all of the latter
[12:23 PM]<wikiuser>     hrm
[12:23 PM]<alexander>     Remember, OurInternal is only accessable to people in TheDepartment & TheJavaPeople at this point.
[12:24 PM]<wikiuser>     yea
[12:24 PM]<alexander>     TheDepartment is only viewable to people in TheDepartment
[12:24 PM]<wikiuser>     and kbase article will be pushed to another web o make them public?
[12:24 PM]<alexander>     And I wouldn't put any TopSecretStuff in the wiki
[12:24 PM]<alexander>     yep
[12:24 PM]<alexander>     we're working out that process now
[12:24 PM]<wikiuser>     not that we will put TopSecretStuff in there
[12:24 PM]<wikiuser>     but that we have tools that allow us to look them up
[12:25 PM]<alexander>     You might want to have your own web for now, then.
[12:25 PM]<wikiuser>     k
[12:25 PM]<alexander>     Once we figure out how to do page-level permissions in version 4.0, we can integrate your stuff with TheDepartment.
[12:25 PM]<wikiuser>     ok
[12:25 PM]<alexander>     But this is going to make the information harder to search for.
[12:26 PM]<alexander>     Which means it'll be less useful to lots of folks.
[12:26 PM]<alexander>     But for the sake of security it sounds like the way to go
[12:26 PM]<wikiuser>     theory question
[12:26 PM]<alexander>     k
[12:27 PM]<wikiuser>     are people making directory structures for topic inside a web (e.g. OurInternal/Procedures/MakingNewWikiPages/Start) or are they doing it on a single level (e.g. OurInternal/StartToMakeNewWikiPages
[12:27 PM]<wikiuser>     and which are we encouraging
[12:28 PM]<alexander>     everything is on one level.
[12:28 PM]<wikiuser>     k
[12:28 PM]<alexander>     which is enforced by the wiki.
[12:28 PM]<wikiuser>     k
[12:28 PM]<alexander>     It requires that people think carefully about topic names
[12:28 PM]<wikiuser>     seems to me that a structure would lend itself to better permissions control
[12:28 PM]<alexander>     For instance, "DesktopError" might not be a good topic name.
[12:28 PM]<alexander>     Subwebs are a feature of 4.0
[12:28 PM]<wikiuser>     k
[12:29 PM]<wikiuser>     so I am ahead of the game
[12:29 PM]<alexander>     yep
[12:29 PM]<alexander>     Wikis are not designed to keep information from people.
[12:29 PM]<wikiuser>     I am just having trouble fitting my square peg in this round hole
[12:29 PM]<wikiuser>     agreed
[12:29 PM]<wikiuser>     but for some of what we are doing, it is necessary
[12:30 PM]<alexander>     And that tendency hurts the entire project. Everyone wants their little secret webs, which means that everyone will end up reproducing other people's efforts and nobody will be able to share information. It sort of gets to me.
[12:30 PM]<alexander>     That's definitely one area where wikipedia has done a great job--keeping people together and making them collaborate.
[12:31 PM]<alexander>     For our internal efforts, the privacy is ultra useful
[12:31 PM]<wikiuser>     yea
[12:31 PM]<alexander>     And it has its place, but I think a big public web for the UMN community would be a good thing.
[12:31 PM]<wikiuser>     agreed
[12:31 PM]<alexander>     Let people push their data up to it as they see fit.
[12:32 PM]<alexander>     Anyway, I'm gonna get off my soapbox now and get back to werk.
[12:32 PM]<alexander>    
[12:32 PM]<wikiuser>     one thing that has set me off about the TheDepartment web effort in general is that information for the same problems/questions is in 5 different places and hardly any of it is right and/or you've got to know the answer to find it...
[12:32 PM]<alexander>     That is a problem, absolutely.
[12:33 PM]<alexander>     The problem stems from the University Departmentality, I think.
[12:34 PM]<alexander>     Everyone's trying to grab turf.
[12:34 PM]<wikiuser>     yes...everyone wants to be the vanguard of something.
[12:34 PM]<wikiuser>     regardless of whether it is re-inventing the wheel
[12:34 PM]<alexander>     These things will sort themselves out, I'm certain. Let's get people using the wiki, and down the line we'll have an army of people willing to work on the public web.
[12:34 PM]<wikiuser>     with a new name or style sheet
[12:34 PM]<wikiuser>     word
[12:34 PM]<alexander>     Sure.
[12:34 PM]<alexander>    
[12:35 PM]<alexander>     But we should push against the ingrained culture a bit. Soft, steady push.
[12:35 PM]<wikiuser>     agreed

February 01, 2006

XpTrackerPlugin Install Problems on Dakar release of TWiki

For the life of me, I could not get the XpTrackerPlugin for TWiki installed last night. I was up until 1:00 AM trying, though. What I wouldn't have given for a Java-style exception stack trace. I found an obscure reference somewhere online about a bad directory structure hindering the installation, so I'm probably going to go back over the Perl code by hand and see if I can track down the problem.

I don't want to write my own plugin for this, so I'm seeking help from Rafael Alvarez. For the record, here's what headaches look like in January:

TWiki::Plugins::XpTrackerPlugin could 
not be loaded.  Errors were:
Can't call method "getPreferencesValue" on
an undefined value at .../lib/TWiki/Func.pm line 458.
Compilation failed in require at
.../lib/TWiki/Plugins/XpTrackerPlugin.pm line 32.
BEGIN failed--compilation aborted at
.../lib/TWiki/Plugins/XpTrackerPlugin.pm line 32.
Compilation failed in require at (eval 40) line 1.
BEGIN failed--compilation aborted at (eval 40) line 1.

Update

Now, what I learned from this is that you should always TRIPLE CHECK the datestamp on plugins. I was using a plugin from a year ago, not from over the weekend. I checked out the fresh source code from SVN (http://svn.twiki.org:8181/svn/twiki/branches/DEVELOP/twikiplugins/XpTrackerPlugin/), changed the permissions on the files to 755 and copied them into my installation directory--the plugin loaded exactly as expected.

So, hats off to Rafael for his lightning fast response to my question. Now I can track XP projects with ease.

The views and opinions expressed in this page are strictly those of the page author. The contents of this page have not been reviewed or approved by the University of Minnesota.