April 15, 2007

Maven 2 build problems

I'm working on moving the code base for my recently Open Sourced project Arete to Maven 2 from 1.3 and I am genuinely unimpressed with the upgrade. I know that the maven project team put a lot of work into M2, but they should have hired an editor for their documentation.

In fact, I'll rewrite all of their documentation for them if they can help me figure out why my pom.xml is malformed. (Note, I'm sure it's something I've done wrong) When I run my tests, it seems as though the test classes cannot see my main classes. I started from their archetypal build and then added my .java source files to the appropriate locations. The package structure is fine. But the tests fail because they can't see the target/classes, unless I'm missing something.

In a situation like this, I'm supposed to scour the net for more information before I submit my pom.xml and snapshot of my source to their user mailing list. Hopefully someone there can help. I'll be sure to write down the results.

January 28, 2007

Javascript to Laszlo via ExternalInterface: The Missing HelloWorld Example

Ever tried to call functions in Laszlo using JavaScript in the HTML page using the built-in flash.external.ExternalInterface class which is included in Flash Player 8 and above? There isn't exactly a wealth of documentation on how to accomplish the simplest use-case of this, but it can be done very easily.

I have created a simple "Hello World" example that illustrates exactly how to call ActionScript functions in OpenLaszlo shockwave movies from Javascript functions in the HTML page, and vice versa, using the flash.external.ExternalInterface library that comes built-in to Flash 8.

Download HelloWorld Example

ExternalInterface.zip (2 Kb), last updated on 2007.01.28

The example runs on OpenLaszlo "legals" beta, and requires no other JavaScript or ActionScript libraries, and no other Shockwave movies. In order to run the example, simply unzip the helloWorld.html and helloWorld.lzx file into a running OpenLaszlo environment.

Without further ado, here are both of the aforementioned files in their entirety:

<!--
  helloWorld.html
  Copyright 2007 Alexander Saint Croix
  Published under Creative Commons License
-->
<html>
  <head>
  <link rel="SHORTCUT ICON"
    href="http://java.eremite.org/favicon.ico"/>

  <title>
    Javascript to Laszlo via ExternalInterface
  </title>

  <script
    src="../lps/includes/embed-compressed.js"
    type="text/javascript">
  </script>

</head>
<body>
  <button
    onclick='document.getElementById("lzapp").sayHello();'>
    Say Hello to Flash
  </button>

  <div id="app" style="height: 400;">
  <embed
    width="400"
    height="300"
    align="center"
    pluginspage="http://www.macromedia.com/go/getflashplayer"
    swliveconnect="true"
    allowscriptaccess="sameDomain"
    flashvars="lzt=swf&amp;debug=true&amp;lzr=swf8"
    name="lzapp"
    bgcolor="#ffffff"
    quality="high"
    type="application/x-shockwave-flash"
    src="helloWorld.lzx?lzt=swf&amp;debug=false&amp;lzr=swf8"
    id="lzapp"/>
  </div>
</body>
</html>

This HTML file references the embed-compressed.js script that comes with each Laszlo installation. If you unzip the HTML file directly into your context root, please update that path reference, as the example will not work otherwise. The LZX document below must be published in the same directory as the HTML document.

/*
 * helloWorld.lzx
 * Copyright 2007 Alexander Saint Croix
 * Published under Creative Commons License
 */
<canvas width="400">
<simplelayout axis="y"/>
<text id="t01" width="400"></text>
<button id="b01" 
  onclick="sayHelloBack()">
  Say Hello Back to JavaScript
</button>

<script>
var c = flash.external.ExternalInterface.
    addCallback("sayHello", null, sayHello);
var iter = 0;
function sayHello () {
  ++iter;
  var out1 = "JavaScript has said hello ";
  var out2 = " times!"
  Debug.write(out1 + iter + out2);
  t01.setAttribute('text', out1 + iter + out2 );
}

function sayHelloBack() {
  LzBrowser.loadJS('alert("hello back")');
}

  LzBrowser.loadJS('document.getElementById("lzapp").sayHello()');
</script>
</canvas>

This file tells JavaScript to call its sayHello function upon successfully loading, so you will know immediately whether you have correctly installed the code. I tested this example on Firefox 1.5 and IE 6.x on Windows, and will provide more information or fix any bugs which anyone brings to my attention. Remember--in order for this to work, you must have version 8 or higher of the Flash Player installed in your browser!

Enjoy!

March 06, 2006

BCEL: lighter than it looks

I mentioned BCEL earlier, but forgot to note the most wonderful thing I've learned about it. It's included in the JDK with Java 5.0. So, if you're working on some ultra-lightweight package and you want a small footprint for the purpose of embedding your software, have no fear.

BCEL is built in. Look in com.sun.org.apache.bcel.**.*

No time for reflection

This weekend I reintroduced myself to Java bytecode engineering by way of BCEL and AspectJ. It is a shame that AspectJ is still not capable of being integrated into IntelliJ IDEA. I elected to set up Eclipse solely for the purposes of conducting aspect-oriented profiling and tracing. This is beneficial in the end because it forces me to keep the aspects completely from the rest of my codebase. I'll very likely not be shipping them with the final release of the project I'm currently working on.

I came up against a possibly major performance bottleneck in my design wherein I use reflection to invoke various methods on POJOs. I was worried for about three minutes. After a brief google search, I found a very helpful article on Java bytecode engineering and how to use BCEL for runtime class generation. I can now wrap up the POJOs at runtime with some just-in-time glue code and make the method calls directly instead of through reflection.

That's great.

Very soon I'll make a major public announcement about the project I've been squirreled away working on for the whole of the last month. I want to make sure I have my legal ducks in a row before I release any of the code, and I want to make sure that its features justify my evangelism. I think they will.

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

January 28, 2006

Trying to access topic preferences from another topic in TWiki?

Here's a letter I just wrote to Michael Daum:

Hi, Micha!

I'm still working on Java.eremite.org. I customized the Nat skin so that if I've got a Topic-Level preference called %TOPICTITLE% it overrides the element in the HTML output. It's great, and it's instantly improved my google rankings. I also now place</p> <p>---+ [[%TOPIC%][%TOPICTITLE%]]</p> <p>at the top of my pages, which further assists the search engines.<br /> Now I'm trying to do the same thing for my internal search results. I'm hoping to figure out a way to grab onto that topic-level preference from another topic, preferably as part of a search. Do you know of any way currently to do such a thing?</p> <p>If so, I'd be extremely grateful to hear about it.</p> <p>Cheers,<br /> -- <br /> Alex</p> <p><br /> </p> <p class="entry-footer"> <span class="post-footers">Posted by <a href="http://blog.lib.umn.edu/saintx/eremite/alexander_saint_croix.html">Alexander Saint Croix</a> on 28 January 2006 at 05:54 PM</span> <span class="separator">|</span> <a class="permalink" href="http://blog.lib.umn.edu/saintx/eremite/2006/01/trying_to_access_topic_prefere.html">Permalink</a> </p> </div> </div> </div> <!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <rdf:Description rdf:about="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#035892" trackback:ping="https://blog.lib.umn.edu/cgi-bin/mt-tb.cgi/7607" dc:title="Drinking Coffee by the Pint" dc:identifier="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#035892" dc:subject="Open Source" dc:description="This morning I am working on the CORM project from inside of the Espresso Royale Caffe in Dinkytown, USA, while drinking coffee by the pint. I think that there are several archetectural problems with the Enterprise Patterns book by Arlow and Neustadt. This morning I am dealing with the problem..." dc:creator="saintx" dc:date="2006-01-22T10:37:03-06:00" /> </rdf:RDF> --> <h2 class="date-header">January 22, 2006</h2> <a id="a035892"></a> <div class="entry" id="entry-35892"> <h3 class="entry-header"> <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/drinking_coffee_by_the_pint.html" class="entry-header" style="text-decoration:none"> Drinking Coffee by the Pint </a> </h3> <div class="entry-content"> <div class="entry-body"> <p>This morning I am working on the <a href="http://java.eremite.org/bin/view/Main/CORM/WebHome">CORM project</a> from inside of the <a href="http://www.espressoroyale.com/">Espresso Royale Caffe</a> in Dinkytown, USA, while drinking coffee by the pint. I think that there are several archetectural problems with the <a href="http://java.eremite.org/bin/view/Main/CORM/EnterprisePatternsMDA">Enterprise Patterns book</a> by Arlow and Neustadt. This morning I am dealing with the problem of persisting Address objects.</p> <p>Persistence requires some sort of identity mechanism inside of the datastore, by which we can refer to a given object. Each object should be uniquely identifiable within the datastore. Inside of the Enterprise patterns book, however, few of the archetype patterns mention their method of Identity.</p> <p>The Party archetype has a predefined PartyIdentifier archetype, which can be used to uniquely determine the party in the datastore. However, a Party can have multiple Address objects. How do we identify those? "No problem," you might be thinking, "just use the PartyId object." Ah, but therein lies the rub--an address may belong to multiple parties. For instance, I share an address with my roommate, <a href="http://www.theinquirer.net/?article=27976">Charlie Demerjian</a>. He's a party (and a riot, but that's beside the point). We both share an address with his company, Stone Arch Network Solutions. SANS is also a party. I also have an e-mail address, which is not the same as my street address. Thus, I have multiple addresses, and some of my addresses belong to multiple parties. Clearly, Address objects require their own ID object. </p> <p>Which is not a problem, really--it's just that the <a href="http://java.eremite.org/bin/view/Main/CORM/EnterprisePatternsMDA">Arlow/Neustadt book</a> didn't forsee that need. The whole episode serves as a reminder not to follow any map off a cliff, and it reinforces my willingness to deviate from the insanity of MDA to create a working implementation of these patterns.</p> <p class="entry-footer"> <span class="post-footers">Posted by <a href="http://blog.lib.umn.edu/saintx/eremite/alexander_saint_croix.html">Alexander Saint Croix</a> on 22 January 2006 at 10:37 AM</span> <span class="separator">|</span> <a class="permalink" href="http://blog.lib.umn.edu/saintx/eremite/2006/01/drinking_coffee_by_the_pint.html">Permalink</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/drinking_coffee_by_the_pint.html#comments">Comments (0)</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/drinking_coffee_by_the_pint.html#trackback">TrackBacks (0)</a> </p> </div> </div> </div> <!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <rdf:Description rdf:about="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#035336" trackback:ping="https://blog.lib.umn.edu/cgi-bin/mt-tb.cgi/7275" dc:title="Introducing java.eremite.org" dc:identifier="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#035336" dc:subject="Open Source" dc:description="I'd like to introduce java.eremite.org. This is a clearing house for documentation related to Open Source software development projects. I built this site in order to publish documentation and tutorials on Open Source software. As Open Source and agile development practices grow in popularity in software development, it becomes increasingly..." dc:creator="saintx" dc:date="2006-01-13T11:38:53-06:00" /> </rdf:RDF> --> <h2 class="date-header">January 13, 2006</h2> <a id="a035336"></a> <div class="entry" id="entry-35336"> <h3 class="entry-header"> <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/introducing_javaeremiteorg.html" class="entry-header" style="text-decoration:none"> Introducing java.eremite.org </a> </h3> <div class="entry-content"> <div class="entry-body"> <p>I'd like to introduce <a href="http://java.eremite.org">java.eremite.org</a>. This is a clearing house for documentation related to Open Source software development projects. I built this site in order to publish documentation and tutorials on Open Source software. </p> <p>As Open Source and agile development practices grow in popularity in software development, it becomes increasingly obvious that the old method of documentation publishing isn't sufficient to cover topics in Open Source. Writing a book for six to nine months, and then releasing it to a three month shelf-life in print makes little sense when the project is under continuous development and refactoring.</p> <p>Similarly, trying to publish instructive articles in technical journals, and online news sites about Open Source pits writers with the inability to update their documentation for their online audience. Because so many people are available and willing to comment about the writing on sites such as TSS and Java.net, the documentation quickly accumulates rust in conspicuous places.</p> <p>For some technologies that are based on standards such as the JCP, writing in this old method is more acceptable, because there is a well-known and documented public standard for much of the API and functionality. However, developers seeking to bring implementations of these software standards to market are required to make choices in the grey-spaces of the public contract. The difficulty for technical writers in the standards-compliant Open Source space lies first in covering the broad standard APIs, and second in accurately covering the margins.</p> <p>Outside the standards, however, another world is teeming and active. New projects are cropping up which are purely experimental. The projects push languages to their breaking points, and are not as concerned with implementing known standards, but in altering fundamentally what it is possible to do with software. These sort of projects are highly mutable, with shifting APIs and constantly evolving documentation.</p> <p>The answer is not to write shorter books more frequently, standards with fewer ambiguities or to republish (and re-sell) slightly different versions of the same document on sites like TSS. Authors need the ability to bring high-quality documentation to the market, ensure that it remains high quality both factually and aesthetically, ensure that they are always given due credit for their efforts, and that it isn't hijacked by less professional writers.</p> <p>There is, to my knowledge, no mechanism or infrastructure which presently permits this. Blogs, perhaps. But blogs are not built to be altered over time. They're built to serve as a daily log. Blogs aren't built on version control systems. Wikis are, but the "wiki culture" tends to kill quality technical documentation and wikis are also notoriously designed to present information in a single shallow context. There is to date no wiki capable of presenting and organizing information with respect to its larger context.</p> <p>So, half measures are required while I continue to build this infrastructure. I've decided to install my own wiki, look toward integrating a web log plugin with it, and use that for quickly building up documentation on my most experimental Open Source projects. I expect the new infrastructure will immeasurably aid me in my work.<br /> </p> <p class="entry-footer"> <span class="post-footers">Posted by <a href="http://blog.lib.umn.edu/saintx/eremite/alexander_saint_croix.html">Alexander Saint Croix</a> on 13 January 2006 at 11:38 AM</span> <span class="separator">|</span> <a class="permalink" href="http://blog.lib.umn.edu/saintx/eremite/2006/01/introducing_javaeremiteorg.html">Permalink</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/introducing_javaeremiteorg.html#comments">Comments (0)</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/introducing_javaeremiteorg.html#trackback">TrackBacks (0)</a> </p> </div> </div> </div> <!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <rdf:Description rdf:about="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#035048" trackback:ping="https://blog.lib.umn.edu/cgi-bin/mt-tb.cgi/7108" dc:title="Apache repository for maven jars to replace iBiblio" dc:identifier="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#035048" dc:subject="Open Source" dc:description="Index of /java-repository at the ASF is a suitable replacement for much of what is at iBiblio. I've found it much more reliable and accessible, so plan to use it as my default repo listing in maven from now on, along with my own repo at eremite.org. I've also decided..." dc:creator="saintx" dc:date="2006-01-09T03:11:29-06:00" /> </rdf:RDF> --> <h2 class="date-header">January 09, 2006</h2> <a id="a035048"></a> <div class="entry" id="entry-35048"> <h3 class="entry-header"> <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/apache_repository_for_maven_ja.html" class="entry-header" style="text-decoration:none"> Apache repository for maven jars to replace iBiblio </a> </h3> <div class="entry-content"> <div class="entry-body"> <p><a title="Index of /java-repository" href="http://apache.mirrorplus.org/java-repository/">Index of /java-repository</a> at the ASF is a suitable replacement for much of what is at iBiblio. I've found it much more reliable and accessible, so plan to use it as my default repo listing in maven from now on, along with my own repo at eremite.org.</p> <p>I've also decided to postpone making the upgrade to maven 2.0 until a more complete set of documentation comes out. After all these years, I can't believe they still don't make a standard set of example applications. In the Drools project, we made sure to have numerous example applications to show people how to use our rule engine. And the strategy paid off in full over the long run. Maven 2 should follow our example on this.</p> <p>Now that I'm back to using maven 1.0, I'll need to start rolling out releases of my source code and jars for the CORM project. I'll write about that project very soon.</p> <p class="entry-footer"> <span class="post-footers">Posted by <a href="http://blog.lib.umn.edu/saintx/eremite/alexander_saint_croix.html">Alexander Saint Croix</a> on 9 January 2006 at 03:11 AM</span> <span class="separator">|</span> <a class="permalink" href="http://blog.lib.umn.edu/saintx/eremite/2006/01/apache_repository_for_maven_ja.html">Permalink</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/apache_repository_for_maven_ja.html#comments">Comments (0)</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/apache_repository_for_maven_ja.html#trackback">TrackBacks (0)</a> </p> </div> </div> </div> <!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <rdf:Description rdf:about="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#035018" trackback:ping="https://blog.lib.umn.edu/cgi-bin/mt-tb.cgi/7106" dc:title="Nothing slows me down like iBiblio" dc:identifier="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#035018" dc:subject="Open Source" dc:description="While trying in desparation to download the commons-lang-2.0.jar from iBiblio's index of /maven/commons-lang/jars, I realized that I've wasted the better part of the last hour and a half fighting with iBiblio. Like some intemperate greek thunder-god, this Zeus of the Open Source Java world demands fealty, subservience, and a life-hemorrhaging..." dc:creator="saintx" dc:date="2006-01-09T00:26:12-06:00" /> </rdf:RDF> --> <a id="a035018"></a> <div class="entry" id="entry-35018"> <h3 class="entry-header"> <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/nothing_slows_me_down_like_ibi.html" class="entry-header" style="text-decoration:none"> Nothing slows me down like iBiblio </a> </h3> <div class="entry-content"> <div class="entry-body"> <p>While trying in desparation to download the commons-lang-2.0.jar from iBiblio's <a title="Index of /maven/commons-lang/jars" href="http://www.ibiblio.org/maven/commons-lang/jars/">index of /maven/commons-lang/jars</a>, I realized that I've wasted the better part of the last hour and a half fighting with iBiblio. Like some intemperate greek thunder-god, this Zeus of the Open Source Java world demands fealty, subservience, and a life-hemorrhaging patience I simply cannot summon during a codesprint.</p> <p>I mean, I need this jar NOW. Not three hours from now. My entire build is waiting, hinging on this. But iBiblio cares not. No error message, no apology. Just a stubborn, mechanical tyrant who either scoffs at my requests or is powerless to send a 404 in response to them.</p> <p>I'm going to investigate maven-proxy and get it set up locally as soon as humanly possible.</p> <p></p> <p></p> <p><br /> </p> <p class="entry-footer"> <span class="post-footers">Posted by <a href="http://blog.lib.umn.edu/saintx/eremite/alexander_saint_croix.html">Alexander Saint Croix</a> on 9 January 2006 at 12:26 AM</span> <span class="separator">|</span> <a class="permalink" href="http://blog.lib.umn.edu/saintx/eremite/2006/01/nothing_slows_me_down_like_ibi.html">Permalink</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/nothing_slows_me_down_like_ibi.html#comments">Comments (0)</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/nothing_slows_me_down_like_ibi.html#trackback">TrackBacks (0)</a> </p> </div> </div> </div> <!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <rdf:Description rdf:about="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#034968" trackback:ping="https://blog.lib.umn.edu/cgi-bin/mt-tb.cgi/7083" dc:title="Road-coder's haven: the Apollo Café in Milwaukee" dc:identifier="http://blog.lib.umn.edu/saintx/eremite/open_source/index.html#034968" dc:subject="Open Source" dc:description="It is not often that I will write a rave review of a Café, but the Apollo in Milwaukee (1310 E Brady St, across from Rochambo) is like a dream come true, especially for a road-coder like myself, away from home over a holiday. Excellent dining meets good, honest, black..." dc:creator="saintx" dc:date="2005-12-28T16:54:54-06:00" /> </rdf:RDF> --> <h2 class="date-header">December 28, 2005</h2> <a id="a034968"></a> <div class="entry" id="entry-34968"> <h3 class="entry-header"> <a href="http://blog.lib.umn.edu/saintx/eremite/2005/12/roadcoders_haven_the_apollo_ca.html" class="entry-header" style="text-decoration:none"> Road-coder's haven: the Apollo Café in Milwaukee </a> </h3> <div class="entry-content"> <div class="entry-body"> <p>It is not often that I will write a rave review of a Café, but the Apollo in Milwaukee (<a href="http://maps.google.com/maps?q=apollo+cafe+milwaukee&btnG=Search&sll=37.062500,-95.677068&sspn=52.770440,66.972656&t=&hl=en&latlng=43038889,-87906389,5653636602594261337">1310 E Brady St, across from Rochambo</a>) is like a dream come true, especially for a road-coder like myself, away from home over a holiday.</p> <p>Excellent dining meets good, honest, black coffee (and plenty of it) in a clean, smoke-free, well managed and unobtrusive atmosphere. I highly recommend the food, the prices are excellent, and the entire experience lends itself to study and especially to software development.</p> <p>I found several electrical outlets, and was able to piggyback on the Rochambo coffee shop's wireless network (password protected, you might want to stop in and make a purchase, get the password and relocate across the street for a smoke-free afternoon.) I have been more impressed with this little gem than with any other Café in Milwaukee, including Rochambo and Anodyne, both of which came highly recommended but left much to be desired. I will definitely look forward to stopping into the Apollo during my next visit to Milwaukee.</p> <p class="entry-footer"> <span class="post-footers">Posted by <a href="http://blog.lib.umn.edu/saintx/eremite/alexander_saint_croix.html">Alexander Saint Croix</a> on 28 December 2005 at 04:54 PM</span> <span class="separator">|</span> <a class="permalink" href="http://blog.lib.umn.edu/saintx/eremite/2005/12/roadcoders_haven_the_apollo_ca.html">Permalink</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2005/12/roadcoders_haven_the_apollo_ca.html#comments">Comments (0)</a> | <a href="http://blog.lib.umn.edu/saintx/eremite/2005/12/roadcoders_haven_the_apollo_ca.html#trackback">TrackBacks (0)</a> </p> </div> </div> </div> </div> </div> <div id="beta"> <div id="beta-inner" class="pkg"> <div class="module-search module"> <h2 class="module-header">Search</h2> <div class="module-content"> <form method="get" action="https://blog.lib.umn.edu/cgi-bin/mt-search.cgi"> <input type="hidden" name="IncludeBlogs" value="2820" /> <label for="search" accesskey="4">Search this blog:</label><br /> <input id="search" name="search" size="20" /> <input type="submit" value="Search" /> </form> </div> </div> <style> .module-list .module-list {margin-left: 16px; list-style-type: disc;} </style> <div class="module-categories module"> <h2 class="module-header">Categories</h2> <div class="module-content"> <ul class="module-list"> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/bibliography/" title="">Bibliography</a> </li> <li class="module-list-item">Coding </li> <li class="module-list-item">Hypercontext </li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/mathematics/" title="">Mathematics</a> </li> <li class="module-list-item">Nuclear Power </li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/open_source/" title="I have spent years working in the Open Source Java arena. My interests lean strongly in favor of Declarative Logic, Rule Engines, Unit Testing strategies and Domain-Specific Language design. My primary interest right now is in building the core algorithms for more advanced declarative logic systems, and building a commercial object relational mapping implementation in JDO that I can reuse across my many projects.">Open Source</a> <ul class="module-list"> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/open_source/corm/" title="">CORM</a> </li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/open_source/jpox_jdo/" title="Java Data Objects">JPOX, JDO</a> </li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/open_source/maven_2/" title="">Maven 2</a> </li> </ul> </li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/philosophy/" title="">Philosophy</a> <ul class="module-list"> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/philosophy/contraction_protraction/" title="">Contraction & Protraction</a> </li> <li class="module-list-item">Mechanics </li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/philosophy/metaphysics/" title="">Metaphysics</a> </li> <li class="module-list-item">Moral Realism </li> </ul> </li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/polity/" title="Civic writings on political philosophy, eleutheria, natural law, economic science, and the American experiment in building an eternal Federal Republic">Polity</a> </li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/umn_community/" title="">UMN Community</a> </li> </ul> </div> </div> <div class="module-archives module"> <h2 class="module-header"><a href="http://blog.lib.umn.edu/saintx/eremite/archives.html">Archives</a></h2> <div class="module-content"> <ul class="module-list"> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2007/04/">April 2007</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2007/03/">March 2007</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2007/01/">January 2007</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/12/">December 2006</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/11/">November 2006</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/09/">September 2006</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/08/">August 2006</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/05/">May 2006</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/04/">April 2006</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/03/">March 2006</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/02/">February 2006</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/">January 2006</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2005/12/">December 2005</a></li> </ul> </div> </div> <div class="module-archives module"> <h2 class="module-header">Recent Posts</h2> <div class="module-content"> <ul class="module-list"> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2007/04/maven_2_build_problems.html">Maven 2 build problems</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2007/01/javascript_to_laszlo_via_exter.html">Javascript to Laszlo via ExternalInterface: The Missing HelloWorld Example</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/03/bcel_lighter_than_it_looks.html">BCEL: lighter than it looks</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/03/no_time_for_reflection.html">No time for reflection</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/02/critique_of_xptrackerplugin_fo.html">Critique of XpTrackerPlugin for TWiki</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/02/specifying_multiple_typeshtml.html">Specifying Instances of Multiple Types in PicoContainer</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/02/multiple_constructor_parameter.html">Multiple Constructor Parameters of the Same Type in PicoContainer</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/02/smooth_moves_with_picocontaine.html">Smooth moves with PicoContainer</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/02/xptrackerplugin_install_problems.html">XpTrackerPlugin Install Problems on Dakar release of TWiki</a></li> <li class="module-list-item"><a href="http://blog.lib.umn.edu/saintx/eremite/2006/01/trying_to_access_topic_prefere.html">Trying to access topic preferences from another topic in TWiki?</a></li> </ul> </div> </div> <h2 class="module-header">Links</h2> <div class="module-content"> <ul class="module-list"> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> <li><a href="" target="" title="Last Updated: "></a></li> </ul> </div> <div class="module-syndicate module"> <div class="module-content"> <a href="http://blog.lib.umn.edu/saintx/eremite/atom.xml">Subscribe to this blog's feed</a><br /> <a href="http://blog.lib.umn.edu/saintx/eremite/index.xml">RSS 2.0</a><br /> [<a href="http://www.sixapart.com/about/feeds">What is this?</a>] </div> </div> <div class="module-powered module"> <div class="module-content"> Powered by<br /><a href="http://www.sixapart.com/movabletype/">Movable Type 3.33.uthink</a> </div> </div> </div> </div> </div> </div> </div> </div> <h5><em> 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. </em></h5> </body> </html>