I Have Been Tagged (Twice) Friday, April 06, 2007

I have been tagged twice recently. First by Jason and now by James. I suppose I need to be a good citizen and play along. :)

I am not really sure what the rules are here. I know that I am supposed to list several things that you probably don't know about me. I don't know if these things are supposed to be funny, embarrassing, personal, impressive, inspiring or what. I don't know if knowing the rules would help me figure out what to write anyway so I am just going to jot out some facts and hope that I don't suffer some sort of penalty for any violation I might commit. :)

I am a member of The American Go Association. I love playing Go, although I am not able to make as much time for it as I might like. My commitment to Go seems to come and go with periods when I will play a lot and periods when I don't play much at all. My friend Lianzhou Yu moved out of state a couple of years ago and that has affected my playing time. Lianzhou is one of the top players in The United States and was a great mentor to have access to. A few years ago my friend Brian Gilstrap and I got together in his wood shop (which I am envious of) to build a couple of Go boards. I am pretty happy with the way my board turned out. I wish I played on it more often. As it is, most games I play these days are played on my laptop against GNU Go.

I won the first large poker tournament I ever played in. The tournament was a charity event to benefit The National Alliance For Autism Research (now Autism Speaks). Having an autistic son, I was happy to contribute and participate in the tournament. There were about 130 entrants. When I heard about this event I gathered up the group of guys that I played cards with regularly and we ended up with 11 of us in the tournament. The final table at the tournament (final 10 players) included 4 guys from our group. In one of the final hands I made a mistake and then ended up getting pretty lucky to beat my friend Paul Jensen out of a big pot and that piece of luck put me in a position to win the tournament.

My name is Jeff, and I am a metal head. There, I said it. I am a fan of heavy metal music. Black Sabbath, Iron Maiden, Slayer, Sepultura, Opeth, Lamb Of God... all guilty pleasures.

I enjoy fly fishing. I tie all of my own flies. I fish mostly for trout in the cold water streams and rivers in Missouri. My late father-in-law introduced me to fly fishing more than 10 years ago. I find less time for fly fishing these days but I really enjoy myself when I do make time to get out in the water.

There was a time long ago when I really, really, really needed a haircut. Why didn't anyone approach me and say something like “friends don't let friends have mullets”?

Now I am going to throw to Dean, Lance, Brian, Eric and Nate.

My Mac OS X Bling Saturday, February 17, 2007

I am now about 2.5 weeks in to my MacBook Pro owning experience. I will say that I am really really happy with the experience so far. I have tinkered with the idea since OS X was introduced and finally decided to give it a go. I am going to provide a rundown of apps I have installed and use. This is everything (I think) that I use that isn't part of the standard OS X install that came with the hardware. If you are an OS X user then at least some of these you already know about but maybe there will be a couple new ones here for you.

Firefox
To be honest, I didn't even give Safari a shot. One of the first things I did was download Firefox. Maybe I should look at Safari, but I probably won't unless at some point I hear/read something that gives me some specific reason to do so.

Desktop Manager
This is a virtual desktop switcher with nice effects (bling) when switching desktops like the rotating cube and others. VirtueDesktops has some nice features but it crashed more than once for me. I may look again when the next release comes about.

TextMate
TextMate is The Full Schizzle. If you edit text (xml, java, c, ruby, groovy, screenplays, etc...) TextMate is for you. If you aren't familiar with TM, visit the site and watch some of the screencasts.

SnapZ Pro X
This is really nice software for recording screencasts.

Adium
Adium is an IM client that allows me to connect to MSN, Yahoo, AIM, Google Talk, ICQ, Jabber and others.

Skype
Skype is another messaging client. The only reason I have this in addition to Adium is that I have a meeting once a week with some folks overseas and we do that over Skype using its group voice capabilities.

NeoOffice
OpenOffice for the Mac. I haven't used it enough to say for sure if I really like it, but so far it is fine.

iRed Lite
iRed Lite is a utility that lets me use the standard MacBook remote control to control more applications than it otherwise does, like NeoOffice, PowerPoint and others.

QuickSilver
A slick utility similar to the built in Spotlight but a little nicer to use, at least for some things.

Spanning Sync
This lets me sync my desktop iCal with my public Google calendar, which I really like. The main site says "coming soon" but betas are available now.

Goban
I don't play computer games, except for Go. This is a nice Go client.

Blender
An awesome 3D animation tool. The movie Elephant's Dream was created with Blender. The entire movie is distributed under a Creative Commons license so you can get all of the production files for free and monkey with the movie if you want to.

StuffIt Expander
I don't have much to say about this one but I use it and include it here for completeness.

Standard dev tools that really aren't peculiar to OS X but I happen to use on my MacBook Pro...

Eclipse, NetBeans and IntelliJ IDEA
I have installed all 3 IDEs. I use Eclipse primarily. I installed NetBeans because I am about to start doing NetBeans Platform development and need to get familiar with the environment. I installed IntelliJ for no particular reason other than I have a license for open source development, though I haven't used it in a couple of years.

I also use Groovy, Grails, JRuby, Ant and the Subversion Client.

I would be happy to hear about your favorite OS X applications.

Groovy And Others Continue To Expand The JVM Horizon Saturday, January 20, 2007

We have had the JVM for over a decade now. There are a whole lot of languages out there that allow developers to build applications for the JVM. The most popular of course is Java. The alternative languages cover the whole spectrum including Lisp, Scheme, Logo, Tcl, Cobol, Ada, Python, Forth, Fortran, Pascal and on and on and on. Why would so many people spend so much effort developing new languages for the JVM or bindings for existing languages to run on the JVM when Sun already went to the trouble of developing the Java language? That is a fair question. The answer varies from case to case. Many of the languages built for the JVM were academic exercises but certainly not all of them. Part of the answer is the fact that the JVM is a fantastic platform for deploying applications but the Java language is not always the best solution for the job at hand.

Among the wide array of languages for the JVM, a few languages have poked their heads up as key players lately. In particular, dynamic languages are getting a lot of attention, for good reason. Of those dynamic languages at this point Groovy and JRuby are among the most popular.

JRuby is a pure Java implementation of the Ruby programming language bringing the power and flexibility of Ruby to the Java platform. One of the significant contributors to Ruby's success is the Ruby On Rails web application framework. JRuby promises to bring that power and flexibility to the JVM. JRuby is a great tool for folks who want to write Ruby code for the JVM but JRuby is not what I want to talk about today. I want to talk about Groovy...

Groovy is a dynamic language written specifically for the JVM. Groovy has a syntax that in many areas is going to be really familiar to Java programmers. Like Ruby has Ruby On Rails, Groovy also has a framework for agile web development and that framework is Grails. Grails has taken a whole lot of inspiration from Ruby on Rails and is a really powerful and fun way to build web applications for the JVM. Grails is bringing the "coding by convention" paradigm to Groovy web programming in a way that is really appealing to developers already familiar with Java's syntax and the rich capabilities of the JVM.

So What Is Happening With Groovy And Grails?

So much is going on with Groovy and Grails right now. The Groovy community has been on track for a long time now knowing that 2007 was going to be a big year. Now that 2007 is here, Groovy and Grails are really in their groove. ;)

Here are some of the things stirring in that community right now:

- Groovy has just released version 1.0. The Groovy community has known that this was coming and having 1.0 out there on the shelves now is a big win for Groovy.

- Manning has recently published Groovy In Action, known as GINA. GINA is being referred to as "Groovy's Pick Axe Book" (a reference to Dave Thomas' definitive guide to Ruby, Programming Ruby). That is not because GINA was the first major book published on Groovy. This has more to do with GINA's clear, direct and thorough coverage of the language.

- Apress has recently published The Definitive Guide To Grails. In The Definitive Guide, Graeme Rocher presents Grails with a real nuts-and-bolts feel that takes developers through comprehensive coverage of the Grails framework.

- Morgan Kaufmann has recently published Groovy Programmers: An Introduction for Java Developers. I have not had time to read Kaufmann's book yet but I think having another general coverage book out there is probably a good thing.

- Jay Zimmerman and Scott Davis have gone live with http://www.aboutgrooy.com/, a great one stop shopping portal for all things Groovy and Grails.

- InfoQ recently published Jason Rudolph's minibook Getting Started with Grails, providing another source of Grails coverage and bringing Grails to the attention of more folks.

- The 2007 No Fluff Just Stuff Symposium Tour is dedicating significant track time to both Groovy and Grails. NFJS has always responded to the community by presenting what developers know is going to be important and the timing is just right this year for the tour to bring Groovy and Grails to the forefront.

- Skills Matter has announced the first 3 day Grails eXchange 2007 event. Grails eXchange focuses on Groovy and Grails in addition to providing tracks dedicated to Java Entperise Edition (JEE) and Ajax/Web 2.0.

- Sven Haiges has announced that his series of Grails podcasts is going to expand to include general Groovy coverage. Sven's podcasts have been a great asset to the Grails community and opening that up to include more Groovy coverage is going to be great for the community.

- Some recent podcasts of interest include Scott Davis' interview with Guillaume Laforge, an interview with Jay Zimmerman and an interview I did with Sven Haiges for the Grails Podcast series.

Developers and Enterprises that are interested in building applications for the JVM are going to find that Groovy solves a lot of their problems really well. All of those Java developers out there will find that learning "The Groovy Way" is not a difficult task and the benefits are fantastic. Combine all of that with the fact that writing Groovy code is just plain fun and you have got a recipe for success.

If you don't already know why so many people are getting excited about Groovy, pickup a copy of GINA and start tinkering. As you start developing your Groovy Kung Fu you will start to question many aspects of "the old way" that have been taken for granted for so long now. Many things about Groovy "just make sense".

Have Fun!

Next Grails Release Coming Soon Wednesday, January 10, 2007

After a bit of a development slowdown around the holidays the Grails development team is back at full throttle working on the next release. Version 0.4 is probably going to be ready to ship within the next few weeks. Version 0.3 was a really significant release in terms of new functionality and addressing some key issues that had been lingering. I feel like 0.4 is even more significant. The team is working hard to add new functionality and also filling in a lot of those little nuisance gaps.

Things are really ramping up in the Grails community. We are seeing folks coming up with interesting plugins. The mailing lists are very active. If you haven't taken a look yet, give Grails a spin. The Quick Start Guide doesn't even scratch the surface of capabilities but is a good first step. Following that guide will take about 10 minutes and you will have a simple CRUD application up and running.

Stay tuned for exciting things from Grails in the coming months.

Groovy 1.0 Has Been Released! Tuesday, January 02, 2007

Finally, after a lot of waiting and a lot of work from the Groovy dev team, Groovy 1.0 has been released.

Thanks to the Groovy dev team for working through all of the challenges, hassles, debates, hard work etc. that were all part of getting to 1.0.

2007 is going to be a big year for both Groovy and Grails. I am proud to be a member of the Grails development team and I am looking forward to what 2007 holds in store for us.

As one of my mentors is fond of saying... Press On!

Groovy 1.0 RC2 Released Saturday, December 23, 2006

Groovy 1.0 RC2 was released today. If all goes well over the next few days the 1.0 release should be available by year's end. The community has been waiting a long time for this. All of the hard work and patience from the Groovy development team is about to pay off. Thanks Guys!

Have A Groovy Christmas!

The Definitive Guide To Grails Saturday, November 25, 2006

The Definitive Guide To Grails is finally available from Apress. The book is a well written easy read that provides a great foundation for Grails developers.

Manning's Groovy In Action (GINA) has been available through their Early Access Program for several months now. The final version of GINA will be available in the next month or so.

Things are heating up in the Groovy and Grails communities. Look for a lot of exciting things to be happening around Grails soon.

Grails 0.3 Released Thursday, November 09, 2006

Grails 0.3 was released today. A lot of work went in to this release which addresses over 100 bugs and feature requests. In my opinion, the fact that Grails is currently at 0.3 is a little misleading. The framework is very powerful and stable. There is a lot on the horizon but the tool is very powerful in its current state. Give it a spin.

I have recently joined the Grails development team and I am looking forward to what the future has in store for Grails.

Grails Support For HTTP Method Restrictions Saturday, November 04, 2006

I have committed code to Grails to support a declarative syntax for imposing restrictions on which controller actions may be invoked using which http request methods. See the docs for details.

Grails Enhancement Submitted Saturday, October 21, 2006

I have worked up an enhancement to Grails recently that provides an easy declarative way for application authors to limit access to certain controller actions based on the http request method (PUT, POST, GET, etc...). Generally speaking, applications should not allow destructive operations to be initiated in response to a GET. That isn't the only reason to want to impose restrictions, but it is a common one. With Grails, the only way to deal with this is to put code in your controller to inspect the request object and figure out if the request was a GET, POST or whatever. For the common case where all I want to do is prevent certain actions from being invoked via a GET, I don't want to have to do that. I just want to tell the framework not to allow it. The patch I have worked up does just that. The patch allows code like this in your controller...


class EmployeeController {

// action1 may be invoked via a POST
// action2 has no restrictions
// action3 may be invoked via a POST or DELETE
def httpMethodRestrictions = [action1:'POST',
action3:['POST', 'DELETE']]

def = action1 { ... }

def = action2 { ... }

def = action3 { ... }

}


The patch has been attached to http://jira.codehaus.org/browse/GRAILS-379.

Grails Presentation Thursday Evening Saturday, September 16, 2006

My Grails presentation Thursday evening went very well. Weiqi Gao blogged about the presentation in real time.

The presentation slides are available at http://www.ociweb.com/javasig/knowledgebase/2006-09/. The tone of the whole session was very light and fun. You will see in the notes that I included quotes about Grails from famous people such as John Lennon, Mr. T, Batman and Robin and even Elvis Presley. Each time a celebrity came up in the slides I asked a trivia question about that celebrity and the first person to shout out the correct answer was given a copy of the Groovy In Action MEAP, courtesy of Manning Publishing. Thanks to Manning for those.

There are not many code samples in the presentation slides. During the presentation I built a simple application and along the way applied the concepts that are mentioned in the notes.

Before the presentation there was some discussion among the group about the future of Java and a lot of people in the group agreed that dynamic languages are going to be an important part of what we do in the future.

Learning New Languages, Like Haskell (not Eddie) Wednesday, September 06, 2006

There are a number of reasons for developers to learn new programming languages. One reason is to keep their skills current. Another reason is that many developers simply find learning new languages to be fun. Another reason is that learning new languages forces developers to think about problems differently. That is what I want to discuss.

Learning new spoken languages changes the way people think about problems. Learning new programming languages is no different. When a C++ developer learns Java they can't do pointer arithmetic any more. They can't use multiple inheritance in the same way. What about Ruby and Groovy? The fire marshall is going to shut down the Ruby bandwagon because it is way over capacity right now. I don't think there are any Java developers left who haven't at least tinkered with Ruby. Java developers learn Ruby and then realize things about Java that start to seem fundamentally wrong. Why isn't there a simple syntax in Java for declaring properties like you can in Ruby or Groovy? Why are there so many 1 line getters and setters in the Java world? What about that dynamic typing? That takes some getting used to. On and on... More languages... More examples...

Languages like C++, Java, Ruby and Groovy are all very different languages but at the same time, are all pretty much the same. They are all object oriented. When you write a program in one of those languages you model the business objects, encapsulate logic, pass references around and all of these objects collaborate to solve a problem. OO has been around for a pretty long time now and is an effective way to build systems. If learning different OO languages is beneficial (and it is), what about learning fundamentally different languages? That ought to be valuable as well. I say it is anyway.

I recently spent a little time playing with BF. That is interesting stuff but no sane person is every going to propose that is a good way to write anything. However, learning BF is an interesting exercise. Try to write a simple calculator in BF and you will be forced to think about things differently. Learning BF is strictly an academic exercise.

On a more practical front I have been playing with Haskell lately and am finding it very interesting. Haskell is a functional programming language. Functional programming languages are all about the function. Haskell is a real programming language that is used to build real systems, not just a goofy language to play around with (like BF). At first the language may seem prohibitively useless for its lack of things imperative programmers are used to. For example, there is no destructive assignment in a pure functional language. That means there is no such thing as "x = x + 1". What? How can I write software without basic functionality like that? You can. This "feature" isn't missing from the language (or whole class of languages), it just isn't necessary.

My Haskell Kung Fu is nowhere near sharp enough to provide any kind of tutorial but I will tempt your curiosity with some very basic hello world kind of examples. Take a look at this...


fac 1 = 1
fac x = x * fac(x - 1)


That is a way to write a function in Haskell to calculate factorials. The first line says "factorial 1 is equal to 1". The second line says "factorial of any other number is that number multiplied by the factorial of 1 less than that number". That seems pretty straightforward, doesn't it? If you read those 2 lines of code out loud, it reads almost like you would describe what a factorial is.

If you can follow the factorial example, the fibonacci example below shouldn't be difficult to understand...


fib 0 = 0
fib 1 = 1
fib x = fib(x - 1) + fib(x - 2)


I don't know how functional programmers really think about that but my OO mind thinks of that as 3 overloaded versions of the "fib" function. One takes a 0 as an argument, one takes a 1 as an argument and the other takes any other number as an argument. This could be written in haskell with just 1 function and some "if" blocks but the code above is "the functional way".

A slightly more complicated example is a sort routine like this...


my_sort [] = []
my_sort (x:xs) = my_sort less_than_x ++ [x] ++ my_sort greater_than_x
where
less_than_x = filter (<x) xs
greater_than_x = filter (>=x) xs


The first line there says that the result of sorting an empty list is an empty list. That seems reasonable to me. The rest is another "overloaded" (probably not the terminology the functional crowd would use) version of the same function. This version accepts a list as an argument where x is the first element in the list and xs is the rest of the list. That little syntax turns out to be useful a lot. The result of sorting that list is achieved by concatenating (++) 3 things. The first thing is a sorted copy of everything that is less than x. The second thing in the concatenation is x. The third thing in the concatenation is a sorted copy of everything that is greater than x (actually greater than or equal to x, as we'll see shortly). The labels "less_than_x" and "greather_than_x" are just that, labels. There is no Haskell magic at play there. The lines after the "where" clause define what those labels refer to. "less_than_x" is defined to be everything in xs that is less than x. "greater_than_x" is defined to be everything in xs that is greater than or equal to x. Since "less_than_x" and "greater_than_x" need to be sorted before the concatenation takes place, recursion is taking place.

Some may look at that code and immediately conclude that it is confusing to look at and can't possibly be a good way to write code. However, once you understand how each of those pieces work, this is really a pretty direct expression of what is being accomplished.

Maybe you will take some time to look at Haskell and find a lot of interesting things about it. If you are really feeling funky and want to explore functional programming constructs in Java, take a look at FunctionalJ. That is interesting to think about but I think from the perspective of tweaking your brain a bit, for a lot of folks learning Haskell is probably a more interesting and more valuable experience.

Enjoy!

Obscure Programming Language Sunday, August 20, 2006

I was doing some research on quines this weekend and while doing so I stumbled across several obscure programming languages that I was not previously familiar with. The following is actual code I wrote that will compile and run (it isn't a quine)...


>++++++++++[>+++++++>+++++++++++>+++++++
+++>++++++++++++>+++>++++++++[<]>-]>-.>+
++++.>-.+++++.---.>-.>++.>-.<<<---.++++.
<++.--.>---.--.<+.>++++++++.<-----.-.>>>+.


Do you know what language that is? A few hints...


  • The language is composed of just 8 commands, each expressed with a single character (7 are used in the program above)

  • Whitespace is insignificant

  • The language is "Turing-Complete"

  • The language has a colorful name (if you reply to this, you may use the initials to avoid the offensive word)

db4o and Groovy Saturday, July 08, 2006

I want to say thanks to Christof and the rest of the gang at db4o as they were kind enough to send me a hardcover copy of The Definitive Guide to db4o. The book showed up this week. I have not had time to read all of it at this point but at a glance it looks like the authors have covered a lot of interesting territory inlcuding replication with Hibernate, which I expect is going to be a big win for db4o in the eyes of a lot of folks.

I have worked up some interesting Groovy integration capabilities for db4o. As soon as I have some time to clean some of that up and get it documented I will be sharing that.

I wish continued success to all of the guys at db4o.

New Groovy Spec Lead Wednesday, June 14, 2006

Today the official announcement was made that Guillaume Laforge is the new Groovy JSR-241 Spec lead.

The whole Groovy community is anxious about the next few months hoping that 1.0 will be finished up. Congrats and good luck to Guillaume!

Groovy And JScience Sunday, June 04, 2006

I have been spending a lot of time investigating Groovy lately. I wanted to dig in to writing a Groovy Category so I started writing some code to support things like this...


def duration = 30.minutes + 2.hours


Before I got too far along there I discovered that John Wilson had already implemented a lot of that in his TimeCategory which is part of Google Data Support.

I had recently read a JNB article that Lance Finney had written on JScience and that gave me another idea. I decided to write a Groovy Category that would use JScience to support things like this...


def len = 2.kilometers + 500.meters


Since I wanted to do this as an exercise I decided to not even do any research to find out if anyone had already implemented something like this. I wanted to build this for my own benefit as a learning exercise. I started by expressing some of my own requirements in the form of a Groovy Unit Test like this...


class JScienceTest extends GroovyTestCase {

void testConversions() {
use(JScienceCategory) {
def len = 2.kilometers
assertEquals 2.0, len.kilometers, 0.00001
assertEquals 2.0E3, len.meters, 0.00001
assertEquals 2.0E5, len.centimeters, 0.00001
assertEquals 2.0E6, len.millimeters, 0.00001
assertEquals 2.0E9, len.micrometers, 0.00001
assertEquals 2.0E12, len.nanometers, 0.00001

def len2 = 400.centimeters
assertEquals 4.0E-3, len2.kilometers, 0.00001
assertEquals 4.0, len2.meters, 0.00001
assertEquals 4.0E2, len2.centimeters, 0.00001
assertEquals 4.0E3, len2.millimeters, 0.00001
assertEquals 4.0E6, len2.micrometers, 0.00001
assertEquals 4.0E9, len2.nanometers, 0.00001
}
}

void testAddition() {
use(JScienceCategory) {
def len = 2.kilometers + 500.meters
assertEquals 2.5, len.kilometers, 0.00001
}
}

void testSubtraction() {
use(JScienceCategory) {
def len = 3.kilometers - 500.meters
assertEquals 2.5, len.kilometers, 0.00001
}
}

void testMultiplication() {
use(JScienceCategory) {
def len = 3.kilometers * 2
assertEquals 6.0, len.kilometers, 0.00001
}
}

void testDivision() {
use(JScienceCategory) {
def len = 42.meters / 3
assertEquals 14.0, len.meters, 0.00001
}
}
}


My Groovy Kung Fu is still developing and I had not done anything at all with JScience before this. Even with those limitations I was able to get all of those tests passing in about an an hour.

Would you rather do this in Java...

Measure length = Measure.valueOf(50, SI.CENTI(SI.METER)).plus(Measure.valueOf(25.0, SI.METER));
Measure lengthInCentimeters = length.to(SI.CENTI(SI.METER));
System.out.println("length in centimeters is " + lengthInCentimeters.getEstimatedValue());


Or do this in Groovy...

def length = 50.centimeters + 25.meters
println "length in centimeters is ${length.centimeters}"


Isn't Groovy fun? :)

Operator Overloading In Groovy Tuesday, May 30, 2006

I have been doing some Groovy development lately. I just spent a few minutes spinning around a quirky behavior that makes perfect sense to me now but at first had me scratching my head. Take a look at this...


def sqlDate = new java.sql.Date(System.currentTimeMillis())
sqlDate += 2


That code is creating an instance of java.sql.Date and adding 2 days to it. My moment of confusion comes from the fact that after adding the 2 days the sqlDate reference no longer points to a java.sql.Date object but instead points to a java.util.Date object. Hmm... What is going on?

The operator overloading is being inherited into java.sql.Date from java.util.Date. The plus method in java.util.Date is returning a java.util.Date, which makes perfect sense. Since that method is inherited into java.sql.Date and not overridden then when it is invoked it returns a java.util.Date.

Try this...


def sqlDate = new java.sql.Date(System.currentTimeMillis())
println sqlDate.class
sqlDate += 2
println sqlDate.class

db4o is pretty interesting Monday, December 05, 2005

I have done a lot of work with a number of Java persistence solutions including JDBC, JDO, Hibernate, JSR-220 Persistence and Prevayler (have just tinkered with Prevayler... no real work). Just recently I started investigating yet another persistence solution called db4objects (db4o). db4o has versions for Java, .NET and Mono. I have only investigated the Java version. In the time that I have spent investigating db4o I have found some pretty interesting stuff.

One thing that stands out is that db4o allows you to persist plain 'ol Java objects as plain 'ol Java objects. POJOs need not extend any magic base class or implement any special interface. POJOs need not have any special id field. POJOs need not have any special constructor. There is no requirement for a no-arg constructor or even a public constructor. db4o doesn't require any object descriptors (XML or otherwise) and doesn't require you to mark persistent classes up with annotations. db4o does not require that persistent fields have Java Bean compliant getters and setters. db4o pretty much will take your objects as they come.

db4o can run in embedded mode which means that all of db4o is inside of your applications process. There doesn't need to be a separate db4o process running somewhere. There can be if that suits your deployment needs, but there doesn't need to be.

db4o has some pretty robust schema evolution capabilities that allow fields to be added, removed and renamed. There is support for moving classes to new packages.

db4o is an OO database. db4o is not an object to relational mapping tool, the db is an OO db.

One of the issues I initially had concerns about was performance once the database accumulated large numbers of objects. To test some of this, I created a fairly simple object model to represent music cds. The classes look something like this...


public class CDArtist {
private String name;
private List<CD> cds = new ArrayList<CD>();
// constructor and methods snipped...
}


public class CD {
private String title;
private List<CDTrack> tracks = new ArrayList<CDTrack>();
// constructor and methods snipped...
}

public class CDTrack {
private String title;
private int trackNumber;
private CD cd;
// constructor and methods snipped...
}


I downloaded a gaboodle of data from freedb.org and wrote a simple parser to turn that data into instances of my classes and started dropping those into my db4o database. At present I have about 75,000 artists, 185,000 cds and over 2,000,000 tracks in the database. I realize that for a lot of situations even those 2,000,000+ tracks don't really amount to a lot of data but that is what I am currently working with. It is enough data to exercise some of the things I wanted to look at.

db4o supports 3 query techniques...



I will show a simple example of each of these here and include some performance figures.

Query By Example (QBE)



The following code uses QBE to retrieve all CDs in the database that contain a track with the name "The Trooper".


Db4o.configure().objectClass(CDTrack.class).maximumActivationDepth(0);
Db4o.configure().objectClass(CDTrack.class).objectField("title").indexed(true);

// my custom factory
ObjectContainer db = ObjectContainerFactory.get().createObjectContainer();

CDTrack myCandidateTrack = new CDTrack(null, 0, "The Trooper");
List<CDTrack> results = db.get(myCandidateTrack);
for (CDTrack track : results) {
CD theCD = track.getCd();
System.out.println(theCD);
}

db.close();



That query completes in less than 300-400 milliseconds. That is querying over 2,000,000 tracks, identifying the ones that match the name "The Trooper" and retrieving the cd that the track belongs to (note the call to track.getCd() inside of the loop).

S.O.D.A.




Db4o.configure().objectClass(CDTrack.class).maximumActivationDepth(0);
Db4o.configure().objectClass(CDTrack.class).objectField("title").indexed(true);

// my custom factory
ObjectContainer db = ObjectContainerFactory.get().createObjectContainer();

Query query = db.query();
query.constrain(CDTrack.class);
query.descend("title").constrain("The Trooper");
ObjectSet<CDTrack> results = query.execute();
for (CDTrack track : results) {
CD theCD = track.getCd();
System.out.println(theCD);
}

db.close();



That S.O.D.A. query executes in about 100 milliseconds. Again querying over 2,000,000 tracks and retrieving the matching tracks and their containing cds.

Native Query



This is what a native query might look like in db4o.


Db4o.configure().objectClass(CDTrack.class).maximumActivationDepth(0);
Db4o.configure().objectClass(CDTrack.class).objectField("title").indexed(true);

// my custom factory
ObjectContainer db = ObjectContainerFactory.get().createObjectContainer();

List<CDTrack> results = db.query(new Predicate<CDTrack>() {
public boolean match(CDTrack candidate) {
return candidate.getTitle().equals("The Trooper");
}
});
for (CDTrack track : results) {
CD theCD = track.getCd();
System.out.println(theCD);
}

db.close();


This approach has some nice benefits. One is that you get real compile time type safety. The query isn't some arbitrary string that might or might not be legal at runtime. The query is real Java code that gets compiled. That is nice. However, that Predicate looks a little suspect to me. Judging from looking at the code it seems that the db4o engine is going to have to create all of my CDTrack objects and pass each of them one a time to my match(CDTrack) method so I can decide which of them match my criteria. Since I have over 2,000,000 tracks that can't be efficient. The code above executes in about 100-150 milliseconds. I am still querying those 2,000,000+ tracks and retrieving all the same stuff I was retrieving in the previous examples. What is going on here at runtime is that db4o is doing some slick class loading voodoo and figuring out what my Predicate would do, then it optimizes all of that away by turning my Predicate into a S.O.D.A. query. Run the code in a debugger and find that my match(CDTrack) method never actually gets called. There are limits here. The optimizer does a good job of figuring out what you intended to do but you can do things in your Predicate that the optimizer can't figure out in which case the Predicate cannot be optimized away and then the engine will have to create all of those CDTracks and pass them to the match method. This is easy enough to sort out at development time if you need to make sure the Predicate will be optimized. While experimenting with this don't try to put a System.out.println call or logging calls in your Predicate to monitor if your Predicate is getting called or not. Those fall in the category of things that the optimizer can't handle and a side effect of them being there is that the method will not get optimized away. There is a callback mechanism you can hookup to retrieve notifications that indicate when a Predicate is optimized and when it isn't.


ObjectContainer db = ObjectContainerFactory.get().createObjectContainer();

((YapStream)db).getNativeQueryHandler().addListener(new Db4oQueryExecutionListener() {
public void notifyQueryExecuted(Predicate filter, String msg) {
}
});


That callback will be notified when db4o first deals with any particular Predicate. The msg argument will by "DYNOPTIMIZED" if the query has been dynamicallly optimized. msg will be "UNOPTIMIZED" if the query could not be optimized. msg will be "PREOPTIMIZED" if the query had been pre optimized. db4o has some bytecode manipulation tools to preoptimize Predicates but I have not investigated that.

They are working on some Hibernate replication modules that will allow a db4o database to be kept in synch with a relational database via Hibernate. That code is still in development and I haven't looked at any of that.

The discussion forums are pretty active and as far as I can tell there is a lot of momentum behind the effort right now.

db4o is distributed under a couple of different license. There is a GPL version available for open source projects, experimenting and internal projects. There is also a commercial license available for commercial, non-open source applications. As far as I know, the GPL version is the same software as the commercial version. The restrictions have to do with distribution, not the software itself.

No reasonable person is going to claim that db4o is the silver bullet of persistence but it is interesting stuff and probably makes a lot of sense for a lot of applications. If nothing else, it is a good thing to be aware of.

Is Sun Pimping The Java Name? Friday, April 29, 2005

Does the name "Java" really belong on these products?

Sun Java Desktop System

Sun Java Workstation W1100z

Sun Java Workstation W2100z

Free IntelliJ IDEA License Thursday, March 03, 2005

A few weeks ago the guys at JetBrains/IntelliJ announced the availability of IntelliJ IDEA licenses that they were making available free of charge to qualifying open source developers. See http://www.jetbrains.com/idea/opensource/ for details.

I already own a current license for IntelliJ IDEA and that license allows me to do whatever development I like (personal, commercial, open source, whatever). I can even install that license on as many machines as I like as long as I am the only person using them. Contrast that with the more limited open source license which is only allowed to be used for open source development and may be limited further to only being used on development of open source projects that the guys at IntelliJ approve. I am not exactly sure about that last part, but the license is limited to open source work. Anyway, because I already own a less restrictive license, the free license doesn't really buy me anything, but I wanted to participate in their program, so I submitted a request based on my involvement with JarSpy. Shortly after sending the request I got an email response letting me know that they have received lots of requests and that each one needs to be evaluated individually and that will be time consuming. I wasn't too worried about it so I saved the email and went on with my business.

Fast forward to today. Today I received an email from them letting me know that they have approved my request and are issuing me a free license. Whooo Hoo! In a way, this is of absolutely no consequence whatsoever. In another way, I am still glad that they are extending this offer and that they are not being overly restrictive about it.

I hope that this helps IntelliJ IDEA continue to grow in its popularity and subsequently leads to its continued life of innovation.