2008-05-09

Problems...

Now with Grails giving me access to all the Java libraries I want... and all the goodness of Grails and Grails plugins... and all the search power in Searchable... I have some problems...

  1. Too many good ideas that now have no significant barriers

  2. Too little free time to do them all at once


... these are good problems to have.

2008-05-06

Multiple versions of Grails in Hudson

I have an interesting situation. I have a Hudson CI server that has to work with two different versions of Grails. I have a somewhat inelegant but functional solution.

First, Grails is set up in:
/usr/local/grails-versions/

each version of grails lives in here so that we have...
/usr/local/grails-versions/grails-0.6
/usr/local/grails-versions/grails-1.0
/usr/local/grails-versions/grails-1.0.1
/usr/local/grails-versions/grails-1.0.2


I create a symbolic link to the current version like so:
 $ ln -s /usr/local/grails-versions/grails-1.0.1 /usr/local/grails
now you can write your hudson jobs to run /usr/local/grails/bin/grails and if you upgrade simply move the symbolic link. Like so:
 $ rm /usr/local/grails && ln -s /usr/local/grails-versions/grails-1.0.2 /usr/local/grails 


Next. Set up your hudson project to ping your SVN server or whatever specifics are needed in your environment to get the code to build. Be sure to name your project a single word ... for example my_project. When you get to the "Build" section you are going to select the "Command" option.

For the sake of argument let's say that you older Grails application is written in Grails 0.6. The command will look something like...

cd my_project &&
GRAILS_HOME="/usr/local/grails-versions/grails-0.6" &&
/usr/local/grails-versions/grails-0.6/bin/grails prod war &&
mv *.war /path/to/build/archive

... where I move my Hudson produced War files to an archive to get picked up by other programs later. You might choose to do something else.

The odd thing I noticed by experimentation is that it's not enough to call on the right grails command... you have to also set the GRAILS_HOME for that command context. If you don't do both then you won't run the right version of Grails.

2008-05-04

Purpose, People, Policy and Social Systems

Last year at BarCampRDU I attended a talk on social sites and their construction. During this talk a UNC professor introduced the "three P's" of social systems. Purpose, People, and Policy. I've been chewing on these ideas ever since.

Incidentally, I encourage everyone to attend a BarCamp and get to know your community thinkers. The BarCamps are a non-profit and non-commercial space to meet with other people interested in changing the world through technology. You won't be sold anything tangible, only ideas.

The "three P's" idea got me thinking about how we live today. The advent of computing has constituted fundamental changes in certain social dynamics that are most easily observed in banking where the person to person relationship of trust has been usurped by computer assisted decision making systems. These systems were intended to augment the decision making ability of loan officers but instead have allowed the abdication of personal responsibility in the decision to grant a loan.

In the past a loan decision was made on the strength of a person's reputation within a community and the loan's collection was enforced primarily by the borrower's desire to maintain the collective good will of that same community. Post industrial society has seen the break down of this organic system and proposed a technological solution... the modern Credit System. In many respects we are all participating, without the ability to opt-out, in a gigantic software beta-test.

The modern digital credit system isn't wrong... its just not quite right yet. It's a beta. Instead we have the challenge as a society to find a way to use a artificial system to enhance the substance of fundamentally and organically human enterprise. We borrow money because we are about the business of doing human things like buying houses, building families, creating jobs.

Many of the currently successful social networking software systems today are successfully finding a way to provide artificial reputation systems akin to the credit bureaus... but without the money. One of my wife's cousins explained to me that (to her at least) the value of MySpace and Facebook was being able to research the reputation of that guy she just met. To her these sites held vital information about her prospective Beau's dating history which could help her avoid a bad relationship.

Scary thought: A credit bureau of dating. Imagine a world where every bit and byte of your social screw-ups were stored forever. Guess what. We live in it. Managing that new social credit system is the burden of every teenager today. And many of these sites (obviously not the ones mentioned...) are worse than beta without a real profit model which could drive them into devious ways to mine that treasure trove of embarrassment.

For many, it seems clear the motivation to join these sites lies in the potential power they have to assist in finding a partner. I won't go into the more crass variations of that. We all know why many young men in Hawaii jump off of cliffs to impress their intended. Filling out a web form with personally identifiable information should seem hardly dangerous at all by comparison.

Clay Shirky has been talking about self-organizing groups lately. This is idea is no surprise to the open-source community. We're all used to it by now. Groups of people gather together for varied motivations to create complex systems that rival or even out perform commercial systems. In Open Source groups, a collective vision forms and is shaped by a charismatic leader and becomes the core of an industry.

It's no surprise we're having a hard time learning to monetize these systems fairly. I personally think the fellas behind TechShop are going to find a way to make this kind of commercial/social enterprise work profitably. I for one will be watching them closely because their business model is at once unique and amazingly simple.

Making a profit from a community does not have to be an evil activity. I'm sure many general store owners in the old west made a profit from their communities without necessarily exploiting the people bought their goods. I think there's a nice story about Abraham Lincoln when he was a general store keeper walking several miles to repay a few cents a customer had over paid. That kind of reputation eventually made him president. I hope that, so too, many of these commercial institutions will find ways to responsibly augment social networks in a trust worthy manner.

Most of these social networking sites are built on startlingly simplistic views of highly complex social systems. Many of their designers proceed from only a rudimentary understanding of how humans interact and how real world reputations are built and lost. Most focus on merely connecting people or associating them without any kind of meaning behind the connection.

In summary, People act in concert for a Purpose. Rarely do they collaborate meaninglessly. People driven by a purpose can do amazing things together. People are directed toward purpose by policy. The policy in a computer system can be artificially imposed by a de facto digital leader of the community. This policy creator can be a person of no real standing or participation in the community whatsoever. That leads to policies completely out of step with the communities that live with them.

It is this disjunct between policy and community that is perhaps the most synthetic of all the attributes of "social networking" systems. I believe that policy-community disconnect will be the downfall of many of the currently popular "web 2.0" sites. As the social group changes its needs the software underneath will fail to adapt and effectively drive away the community that was using it. Fortunes will be won and lost on this exodus of people.

The job of social networking software will be to enforce policy in ways that foster community and help it thrive toward its purpose. Succeed and create a movement. Fail and destroy one. Do neither without a purpose.

2008-05-01

Grails Audit Logging Plugin is a "real plugin"

I'm very happy to be able to post that the Audit Logging Plugin is now available via the "official" Grails plugin install commands. My plugin is no where near as cool as the Searchable Plugin but I'm very pleased to offer it up. I hope it fills a need judging from the relatively large spike in traffic I got from other blogs and sites like refactr I'd say there's quite a few people who might want this plugin.

You know who you are. Now you can send me bug reports!

2008-04-29

Groovy Builders

This is good stuff: "Make a Builder" (I think I'm about to get busy). I also think that this is why Groovy is one of the best languages to work in right now. What I love about that post is that it includes the Java code for how to build a builder and how that then affects your code.

Extending any platform built on Groovy is probably just this simple. The practical examples are absolutely price-less.

2008-04-28

Changing the face of UI

I have talked previously about how I felt about many of the UI building environments out there today. My UI experience comes from a nearly decade old C/C++ experience in CaveGL, OpenGL, and GLUT... so I can't speak much to Java UI. Fact is I've never had to build a full Java UI for a commerical project before. I've only had toy Java UI projects.

Recently, when an opportunity to do real Java UI work landed in my lap, I jumped on it a little too eagerly. In my time working with Java UI I've found that unlike my days with OpenGL and other open source GUI rendering tool kits the ones for Java are comparatively opaque.

Part of what worked well in those "primitive" environments was how easy it was to stumble upon or discover the API and design a system with trial-and-error. My feeling is you can't do this in Eclipse because the system has too many moving parts to just tinker with and discover. I feel strongly that software on any level should encourage play and discovery and be tolerant of screw-ups by the user.

I've also mentioned that UI should perhaps be a descriptive exercise. That is to say that the look of UI should be described and computed. The function should be meticulously programmed but the look and feel should be easily changed and readily played with.

Today I found this project, Java Builder. The idea behind Java Builder is exactly what I've been trying to express in words. Java builder provides a YAML based DSL to describe Java UI. The YAML is turned into straight Java.

This is brilliant work that is moving in the right direction.

2008-04-24

Audit Logging Plugin version 0.3: who did what when

When I posted my Audit Logging plug-in I had no idea how to get at the user name of the person using the session. I posted a question on the Grails Dev forum. And the answer supplied by pftravis lead me this...

static String actorKey = 'userPrincipal.name'
static String sessionAttribute = null

def getActor() {
def attr = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes()
def actor = null
if(sessionAttribute) {
actor = attr?.session?.getAttribute(sessionAttribute)
}
else {
actor = resolve(attr,actorKey)
}
return actor
}

... if there is no configuration the default will read the 'userPrincipal.name' from the context. In my set up of the listener I read in the Config.groovy from the grails project and if there is a configuration like this...

auditLog {
actorKey = "session.user.name"
}

...then I'll use a clever little groovy trick to resolve the session, user, and name out of the attributes. If instead the configuration looks like...

auditLog {
actorKey = "userPrincipal.id"
}

... the same trick will read the id of the authenticated user. But, if you are using CAS then you can do this...

auditLog {
username = "${edu.yale.its.tp.cas.client.filter.CASFilter.CAS_FILTER_USER}"
}

... and you get the CAS authenticated user name.

So long story short all you have to know is if your security system uses userPrincipal and if it does whether "userPrincipal.name" or "userPrincipal.id" is right. If you have a home brew security system all you have to know is what part of the authenticated user you want to identify the user by... and specify "session.user.name" or "session.login" depending on how your security system works. And for systems like CAS you can use an attribute key of any kind.

Nice and generic. Check out the latest Grails Audit Logging Plugin. As always any feedback or criticism will be welcome... and my goal in all of this is to contribute and learn.