JOOP: Java Object Oriented Persistence

Joop is more a proof of concept than a finished project. Joop was born out of an interest in object oriented databases and the observation that many people make use of full RDBMS systems, with expensive object to relational mapping schemes, when simple persistence is really all that is needed. A use case came up in a project I was working on where something like this might be useful, so I took the opportunity try out some ideas I'd had kicking around in my head and solve a real life business problem at the same time. All told, there's only a few days worth of work in here, but the ideas behind it are, to me, anyway, kind of interesting.

Basically, Joop is a framework for creating datastructures that persist themselves to the filesystem. Currently there is only a single data structure implemented, a binary search tree, which implements the SortedMap interface. It's very straightforward-- when you add an object to the map, rather than being stored in memory, it's written out to a file in the filesystem that backs the data structure. The API couldn't be simpler--it's just the Java Collections Framework. Objects are stored and retrieved from the filesystem in a transparent, idiomatic way. The only configuration an application using it is going to need is the path to the file. No network connections, JDBC drivers, connection pools, schemas, or object to relational mappings. Just simple, basic persistence to an arbitrary data structure.

One of the more interesting features of Joop is seamless handling of nested datastructures--even ones that are referenced indirectly. So let's say, for example, that you create an instance, a, of JoopBinaryTreeMap backed by the file 'myjoop.db'. You can now also create an instance, b, that is a child of a, ie it shares the same backing file as a. You can then add b directly to a or, and this is kind of the cool part, you can add an object to a that refers to b and b will work as a full fledged Joop data structure, ie it will leave its member objects in the filesystem until they are retrieved by client code. If that's starting to sound kind of abstract, I can show you this example taken from one of the actual unit tests for Joop:


    public void testNestedDataStructures() throws Exception {
        // Create map file
        File file = File.createTempFile( "TestJoopBinaryTreeMap", "dat" );
        file.deleteOnExit();
        
        // Create a couple of nested maps
        JoopBinaryTreeMap parentMap = new JoopBinaryTreeMap( file, "rw" );
        parentMap.put( "map1", new JoopBinaryTreeMap( parentMap ) );
        parentMap.put( "testObject", new TestObject( "Fela Kuti", new JoopBinaryTreeMap( parentMap ) ) );
        

	// Snip: insert some data into the maps and get them out again
	
	. . . 

        // See, we have a nested datastructure that is an attribute
	// of another Java object
        map = testObject.bar;

	// Snip: more exercising of the map, you get the idea
        
	. . . 
    }
    

The salient point to get from this is that in the above example we have three different instances of JoopBinaryTreeMap seamlessly integrated and all sharing the same database file. As you can see, nested structures do not have to be immediate children of the parent structure, but can even be referenced by standard Java objects that are added anywhere in the object graph. When an object is being serialized to or deserialized from the backing file, if a Joop structure is found, it is handled accordingly. When you couple this behavior with the notion that JoopDataStructure can be extended to implement any data structure you can dream up, not just binary trees or other variations on mapping structures, then you realize that you can create databases of any arbitrary structure you like and handle it all in idiomatic Java at the client level.

I will note, in closing, that I am not proposing a replacement for relational databases or any kind of fully fledged database system. Rather, this is simply an expansion of Java's native object serialization capabilities to allow complex object graphs to be easily maintained in file system. I do think this can make an interesting addition to a programmer's tool chest, to use when appropriate. As is often the case, you do have to match the right tool with the job you're trying to do. Often, as programmers, we get into ruts where we use the same tool for every job simply because we know that tool--not necessarily because it's the best one to use. Maybe this will help someone solve a simple problem without having to resort to a tool that is more powerful and more complicated than is necessary.

Contact:
My email address is 'chris' at this domain.