2008-06-23

Wandering around Research Triangle Software Symposium 2008

My path through the Symposium one was eclectic. This year my needs are in the areas of project management and dealing with software development life-cycle. There comes a point when you realize you have all the right technical tools but you don't have the right soft skills in order to deal with business level problems.

I got to sit through several talks by Jared Richardson. Jared's talks this weekend gave me the perspective that the changes we are after when we say "agile" are there to deliberately limit the number of negative interpersonal interactions and increase the positive interpersonal interactions. If you do that then it doesn't matter what you call it. The technologies that make us "agile" are not panacea but tools to tweak how people deal with each other. Tightening feedback loops between people and creating automations for tasks actually translate into building trust between people and objectivity into assessments of success and failure. This was a major perspective shifting moment for me that left me a little dumb-struck. It was a "there is no spoon" moment.

By Sunday I was really worn down. I'm not a naturally gregarious person and three days of constant crowds get me beat. Besides, how many mind-blowing life-changing talks can you take in three days? So Sunday I geeked out at the technology presentations and I was glad I did.

Venkat Subramaniam covered FP on the JVM. Functional programming is something that I've brushed against repeatedly but never used in the enterprise. I think I share Venkat's predilection for learning new languages I just haven't exercised it as much. I am going to have to teach myself Erlang this year even though I know I'll never use it in production. Erlang will probably show up in this blog from time to time. Remember, this is not a Groovy/Grails blog. Groovy just happens to be what I'm working with both at work and at home right now. I strongly believe that the point of software is the codification of cognition. That means using the tool that best represents that thought and uses the best platform for delivery of that thought. Venkat has definitely raised my interest in some of the FP languages.

I'm so steeped in Groovy lately I thought I should go and get some JRuby exposure. I've never attended a talk on Ruby. I've only bashed my way through Ruby and Ruby on Rails in small toy applications that I developed during research projects over the last few years. Ruby is a very simple and powerful language (and very pretty IMHO) but I think most of what causes resistance to it is how alien it looks. The first time I heard about Ruby was from Bishop while we were in college together.

I ended up getting work using Perl, C, Ada, and sometimes Bash over the years so I never really used Ruby at work. Neil Ford does an excellent job selling JRuby as a next generation JVM language. I did detect that some of his comic jabs at Java were taken as outright insult by some of the more serious Java-heads. And this is why I say: "Never fall in love with technology." It blinds you to objectively evaluating a technology and its capabilities. That goes for all of us Ruby enthusiasts or Groovy enthusiasts alike.

Language is definitely one way to open up your mind about some of these new problems we face dealing with concurrency on multi-core systems. I think that the more important sea-change is in programming paradigm. Not necessarily language. Consider this video floating around on Slashdot (and triJug) featuring Cliff Click. It covers concurrency correctness for a data structure by the use of finite-state-automata with an extra rule: Any state can be a start state. Cliff Click's solution is to create logic in the threads that will allow each one to act correctly no matter what state it finds the data in. Now if only I could get paid to write stuff like that. That's some serious getting your geek-on.

And that stuff is written in Java. Just to prove the point that any Turing complete language can produce the same computational results as any other. It's just a matter of how you get there.

Sunday afternoon I sat through both talks by Jeff Brown the first one by accident actually. I had forgotten to move to see Venkat Subramaniam and hear his take on Guice, but I was glad I stayed to hear both of Jeff's talks. Not only does he have the fantastic style of understating things to great effect but it was an absolute thrill to hear repeated gasps from the audience as he introduced Grails to them.

And here's what's interesting about Grails is that it does get Java people excited. Much more excited than Rails does. I think Grails excites Java developers because it can run in their current environments and hook into what they already have with very little work. Grails is built-up from Spring so they can see how they can leverage what they already know about so many Java tools. And at any point of pain you can fall back to what you know.

I think Grails fills a very neglected need in the Java developer space and that need has been neglected so long because those feedback loops between tool vendors and the common programmer have been broken. As long as the Grails community works to keep those loops closed and to listen to its user population there is a very large niche for Grails in Java-rich shops. The trip to Grails is so much shorter than the trip to Rails. Even Rails on the JVM.

Jeff's second talk taught me several tricks I was missing. I got to talk to him about my Audit Logging plugin and even got a few pointers so I've made a list of things I need to do. Highest on the list is to setup PostgreSQL and get to testing with that configuration. I also got several ideas for new plugins that I could add using what I already know. I should have time for this after July until then all my free development time is double booked.

An interesting question that I got was how does Grails scale? I'm sure most of the answer to that is contained in how does Spring scale? I personally only have production grails apps under modest load some 10 to 15 transactions a second at peak (a peak which is exceedingly rare and my performance upper bound is dependent on two external systems so I had to back my application's speed off to avoid swamping the other system). But, if you want the real answer from some guys with real heavy use scenario experience go take a look at Brian Guan has to say.

The other advantage with Grails is being able to say: "If you find a part that doesn't scale, rewrite it in Java." And I'm not telling a web developer to go dust off her C book instead I'm pointing to an existing infrastructure and expertise one layer below Groovy. One that the developer already has and uses.

For reasons that I'll explain in a later post I have to use two different container managed datasources. The first one drives my GORM for access to objects and the second drives a set of custom DAO to normalize data using some very cleverly hand crafted queries. The DAO gets its data source from Config.groovy in development mode or from JNDI in both test and production mode.

Just because it's never gotten a slide... here's the resource.xml way of grabbing that for Grails...

<bean id="legacyDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/LegacyDS" />
</bean>

... and if I wanted to grab that data source in a groovy object

def legacyDataSource


... sadly I don't always have a JNDI defined data source in my environment so what I did is the less elegant and more bludgeon-ly:

def openDb() {
def conf = ApplicationHolder.application.config
def db
if( conf.legacy.jndi ) {
if(!legacyDataSource) {
def initialContext
// Obtain initial context
try {
initialContext = new javax.naming.InitialContext();
legacyDataSource = (DataSource) initialContext.lookup(conf.legacy.jndi);
} finally {
initialContext.close();
}
}
db = Sql.newInstance(legacyDataSource)
}
else {
db = Sql.newInstance(
conf.legacy.url,
conf.legacy.username,
conf.legacy.password,
conf.legacy.driverClassName
)
}
return db
}

... which switches depending on whether the environment is configured for JNDI or for directly managed connections.

I met lots of folks that I hope keep the Grails enthusiasm through the next year. I think we are at the beginning of a major sea-change in the Java space and I think both Groovy and Grails will be important players in that change. Nobody can predict what's next but Groovy has a way of getting Java people excited. It's been a long time in coming and the need in the RTP area is definitely there. With Cloud Computing for Grails coming along nicely I think we have plenty to be excited about.

2008-06-18

Beginning to understand WebFlow

I'm beginning to understand WebFlows. WebFlow is perhaps the most different part of working with Grails. You don't have to use WebFlows and in fact I think I'd advise people to avoid them until they are very comfortable in Grails. That's because the diagnosis of WebFlow is not as straight forward and intuitive as the rest of Grails. For most of Grails you just do things. With WebFlow you need to think things out.

I've developed an in-elegant technique for working with WebFlows that actually works well for me. I'll refine it a bit and write this up at some point. Hopefully some of the Grails rock-stars out there will help me get straight about it.

I'll be attending the NFJS conference in RTP this week and I plan on taking advantage of the free IntelliJ license. Maybe if I live with it for a while I'll get over myself and start getting productive. The problem is... I really am amazing with vi I've figured out how to use vi inside my current tool-chain and I'm actually quite effective at writing regex and macros in it for refactoring. I lose all that when I switch to a new tool kit so there is significant pain in adopting a new tool. Least of which is a price tag for something you don't know if you can adapt yourself to.

Now attending NFJS in RTP is what turned me on to Groovy and Grails. I happened to have been shopping around for platforms at the time so the timing couldn't have been better. Now I have Grails firmly in hand I'm interested in attending the development process improvement workshops so I can start working more effectively with the tools I currently have and potentially adding new support tools to my tool bag.

2008-06-12

Deploying Grails 1.0.3 on JBoss 4.2.1

Grails version 1.0.3 was recently released and if you blindly try and deploy this on to an old JBoss (I'm using 4.2.1) your deployment might fail giving you this trace:

Exception sending context initialized event to listener instance of class org.codehaus.groovy.grails.web.context.GrailsContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/hibernate/annotations/common/reflection/ReflectionManager
at java.security.AccessController.doPrivileged(Native Method)


You'll need to add the following jars (which you could take from grails-1.0.3/lib if you wanted) to your JBoss server's lib directory...

  1. hibernate3.jar

  2. hibernate-annotations.jar

  3. hibernate-commons-annotations.jar



Why all three? Well, if you don't do all three you'll see...
Exception sending context initialized event to listener instance of class org.codehaus.groovy.grails.web.context.GrailsContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSource': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.AnnotationException: java.lang.NoSuchMethodException: org.hibernate.validator.ClassValidator.(java.lang.Class, java.util.ResourceBundle, org.hibernate.validator.MessageInterpolator, java.util.Map, org.hibernate.annotations.common.reflection.ReflectionManager)

... so drop all three in there and upgrade your JBoss server's version of Hibernate.

2008-06-11

Drinking from the Grail

The idea behind Grail (not to be confused with Grails) has me excited. In particular the idea had come to me earlier but... I'm not Guillaume so it's not like I'm going to pull off an idea like that.

But. Guillaume is Guillaume. So that means he just might pull off this concept.

What's the big idea? It's Guillaume et al's take on CPAN/RubyGems for Java/Groovy land. The biggest strength that Perl had was CPAN. One of the best features of Ruby is the RubyGems which is ostensibly a take on CPAN for Ruby. There have been several attempts in the past at a CPAN for Java but, sadly, none have taken. The same problems that keep a CPAN for C/C++ from existing keep a CPAN for Java from existing... basically build environments get screwy.

But, Groovy is a special beastie in the world of programming languages. It is truly unique in its place because of how closely it matches Java and how it can be run as a script or as a compiled Java class. Jeff Brown gave a nice presentation at TriJug showing how a compiled groovy class' byte code looks just like a Java class' byte code... and that's a nifty trick that takes some people three or four double takes to understand. The compiler is dropping in whole methods for you. Powerful, easy to use, and a little mind-warping. It's probably the number one reason Groovy has had a shallow uptake until now. It has taken time for the community to digest this new paradigm.

It's this interesting hybrid compiled/scripted/synthesis nature of Groovy that could mean a project like Grail could work where other Java archive systems have failed. I suspect that as the project becomes reality we'll find it leaning on Groovy language capabilities more and more under the covers even if it can benefit straight Java projects it will need Groovy in some way. Probably using that MissingClassException feature and some nifty code synthesis tricks... I'm not sure...

Of course I'm just arm-chair-quarter-backing here. It's a rock star like Guillaume who's going to pull this off.

EDIT: And there we have it: Grape ... thanks for pointing that out Andres.

2008-06-09

Lessons learned...

A short list of things I have done wrong recently...

  • Working in GORM/Hibernate if you provide a mapping DSL and intend on your class to move between databases do not assume the default "hilo" algorithm will work on all databases. See id generator documentation at hibernate.org

  • Do not assume that you can throw classes up and down an inheritance hierarchy in Hibernate. For example:

    class Person {
    Long id
    String name
    }
    class Parent extends Person {
    static hasMany = ['kids':Person]
    }

    ... you need to do this to turn a "person" into a "parent"


    def makeParent = {
    Person.executeUpdate( "update versioned Person as p set p.class =:clazz where p.id =:id", [clazz:Parent.class.getName(),id:params.id.toLong()] )
    def parent = Parent.get(params.id)
    if(!parent) {
    flash.message = "Person not found with id ${params.id}"
    redirect(action:list)
    }
    else {
    redirect(controller:'parent',action:show,id:parent.id)
    }
    }


    ... other techniques to do this create a new object with a new id. That means you can't model a "parent" to "child" relationship this way. Instead turn the relationship around ...

    class Person {
    Long id
    String name
    static hasMany = ['parents':Person]
    }

    ... or create a bridge object...

    class Person {
    Long id
    String name
    }
    class Relationship {
    Person parent
    Person child
    }

    ... and that works much better.

  • Do not lock in a domain model based on "big design first" principles. Domain may have to change to fit reality of your system. Sometimes you don't really understand the problem on day 1 or day 10.

  • Do not release big, release small, release frequently. It's better to get tiny releases and adjust course in small increments rather than have "big bang" releases.

  • Coding and posting while tired only lead to messes you have to clean up later.

  • Do not ignore your email.



Hopefully, the insanity has passed.

2008-06-03

Web 2.0 is so last year...

Note: I'm still too busy to write full posts. I should be back to a normal schedule soon.

First there was the web, then Web 2.0, now there's Web 3Di...



Actually, it's a very insightful video. The problem is that 3Di is not just twice as hard as 2.0 it's exponentially harder. Increasing dimensions in a system exponentiates the complexity possible in a system. Now, I'm not just riffing on the name. Actually a decade ago I thought that 3D internet ala Second Life would be main-stream today. I even based my Graduate studies on this. My realization is that these things are actually much much harder than we realize. I think the next decade should see real web 3Di take off. That means really useful 3D web sometime between 2010 and 2020. If that time scale is too big for you... just ignore 3Di for now.

However, I look forward to the day that I can bring back my work in VR and marry it up to my Web based work. I may get to see that day sooner than I thought.