While playing with Groovy and Db4o I ran across a few errors that nearly put me right off Db4o. But after half a day tinkering I have found that it’s not really a problem with Db4o. If you are getting any of the following errors when trying to use Db4o and Groovy then perhaps this post can help.
Errors:
java.lang.ClassCastException cannot be cast to com.db4o.reflect.generic.GenericObject // or person.getClass() is this. // When trying to access a method or property of a retrieved object. groovy.lang.MissingMethodException groovy.lang.MissingPropertyException (G) Person // GenericObject, e.g: println person |
The problem arises when the script tries to open an existing database with objects in it and is something to do with reflection and class loading that Db4o does. Now Db4o is a Java OODBMS and all the examples are in Java, hence compiled before run! None of the suggested solutions that I found around the `net such as using file.canonicalPath or using a new config or packages or using a newer jar (db4o-7.12.156.14667-all-java5.jar) made the slightest difference.
The solution: `groovyc Person.groovy`
That’s correct we need a compiled Java class file so that Db4o can load/reflect or whatever and cast the returned data back to Person instead of creating a GenericObject! Every time Person.groovy changes we need to compile it again otherwise the source file will be used.
Person.groovy:
class Person { String name String toString() { "My name is $name" } } |
Groovy script, PersonExample.groovy:
#!/usr/bin/env groovy import com.db4o.* def db def file = new File("db.db4o") //file.delete() def jack = new Person(name:"Jack") def jill = new Person(name:"Jill") try { db = Db4oEmbedded.openFile(file.absolutePath) db.store(jack) db.store(jill) db.commit() } finally { db?.close() } db = null // Just to be clear. try { db = Db4oEmbedded.openFile(file.absolutePath) def persons = db.query(Person) for(person in persons) { println person } } finally { db?.close() } |
Usage:
– download and place db4o-7.12.126.14142-all-java5.jar in $GROOVY_HOME/lib.
– groovyc Person.groovy
– chmod +x PersonExample.groovy (make the script executable)
– ./PersonExample.groovy or `groovy PersonExample.groovy`