« JavaOne and Oracle Develop | Main | JE, JCA, OC4J »

Berkeley DB Java Edition and JavaFX

Sun recently announced JavaFX, "a new family of Java technology-based products that will help content providers create and deploy rich Internet applications (RIA)".  They also announced "a new scripting language, JavaFX Script
[which] gives Java developers the power to quickly create content-rich
applications for the widest variety of clients, including mobile
devices, set-top boxes, desktops, even Blu-ray discs."

We've always wanted to port JE to Java ME, but for various reasons, never gotten around to it.  JavaFX Script opens the possibility of using JE in an embedded environment and so I thought it would be interesting to verify that it all works ok.  It makes perfect sense to have a lightweight, persistence, ACID storage engine in a JavaFX environment, and since Java FX Script is one of the new class of scripting languages which sit on top of a JVM (e.g. JRuby, Groovy, etc.), it would have surprised me if JE didn't play well with Java FX Script.  Indeed, it was a pretty painless task to get a simple example running.

Here's the sample code:

import java.io.File;
import java.lang.System;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.JEVersion;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.Transaction;

doSomeJEOps();

operation doSomeJEOps() {
var theDb : Database = initJE();
var txn : Transaction = null;

initJE();

txn = theDb.getEnvironment().beginTransaction(null, null);
for (i in [0..9]) {
put(theDb, txn, "foo{i}", "bar{i}");
}
txn.commit();

System.out.println("Retrieval by key: foo0 => {get(theDb, null, 'foo0')}");
var key : DatabaseEntry = new DatabaseEntry();
var val : DatabaseEntry = new DatabaseEntry();
var cursor : Cursor = theDb.openCursor(null, null);
System.out.println("Retrieval by cursor");
while (cursor.getNext(key, val, null) == OperationStatus.SUCCESS) {
System.out.println
("{new String(key.getData())} => {new String(val.getData())}");
}

closeJE();
}

operation initJE() {
var envConfig = null;
var env = null;
var dbConfig = null;
var db = null;
envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
envConfig.setTransactional(true);
env = new Environment(new File("c:/temp/blort"), envConfig);
dbConfig = new DatabaseConfig();
dbConfig.setAllowCreate(true);
dbConfig.setTransactional(true);
db = env.openDatabase(null, "foo", dbConfig);
return db;
}

operation closeJE() {
theDb.close();
theDb.getEnvironment().close();
}

operation put(theDb:Database, txn:Transaction, theKey:String, theVal:String) {
var keyDE : DatabaseEntry = new DatabaseEntry(theKey.getBytes());
var valDE : DatabaseEntry = new DatabaseEntry(theVal.getBytes());
var status = theDb.put(txn, keyDE, valDE);
if (status <> OperationStatus.SUCCESS) {
throw status;
}
}

operation get(theDb:Database, txn:Transaction, theKey:String) {
var keyDE : DatabaseEntry = new DatabaseEntry(theKey.getBytes());
var valDE : DatabaseEntry = new DatabaseEntry();
var status = theDb.get(txn, keyDE, valDE, null);
if (status <> OperationStatus.SUCCESS) {
throw status;
}
return new String(valDE.getData());
}

and the output:
compile thread: Thread[AWT-EventQueue-0,6,main]
compile 0.11
Retrieval by key: foo0 => bar0
Retrieval by cursor
foo0 => bar0
foo1 => bar1
foo2 => bar2
foo3 => bar3
foo4 => bar4
foo5 => bar5
foo6 => bar6
foo7 => bar7
foo8 => bar8
foo9 => bar9
init: 1.332


Comments (3)

Ricardo Rocha:

Terrific example! And, yes, it makes a lot of sense to have a lighweight persistence mechanism such as Berkeley DB...

I took the liberty of rewriting the code to make it more "JavaFXish" so that it shows a few interesting language features:

import java.io.File;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.JEVersion;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.Transaction;

doSomeJEOps();

operation doSomeJEOps() {
var theDb = initJE();
var txn = null;

initJE();

// txn's type is inferred from its first non-null assignment
txn = theDb.environment.beginTransaction(null, null);
for (i in [0..9]) {
put(theDb, txn, "foo{i}", "bar{i}");
}
txn.commit();

// built-in println() provides convenient access to stdout
println("Retrieval by key: foo0 => {get(theDb, null, 'foo0')}");

// Assignment invokes empty constructor. variable type is inferred
var key = DatabaseEntry;

// Assignment invokes empty constructor. variable type is inferred
var val = DatabaseEntry;

// variable type is inferred from first assignment
var cursor = theDb.openCursor(null, null);
println('Retrieval by cursor');
while (cursor.getNext(key, val, null) == OperationStatus.SUCCESS) {
println("{new String(key.getData())} => {new String(val.getData())}");
}

closeJE();
}

operation initJE() {
// var envConfig's type is inferred from assignment
var envConfig = EnvironmentConfig { // empty constructor invoked
allowCreate: true // java properties are set declaratively
transactional: true
};

// var env's type is inferred from assignment
var env = new Environment(new File('c:/temp/blort'), envConfig);

// var dbConfig's type is inferred from assignment
var dbConfig = DatabaseConfig { // empty constructor invoked
allowCreate: true // Java properties are set declaratively
transactional: true
};

// var db's type is inferred from assignment
var db = env.openDatabase(null, 'foo', dbConfig);
return db; // operation initJE's type is inferred from its return value
}

operation closeJE() {
theDb.close();
theDb.environment.close();
}

operation put(theDb:Database, txn:Transaction, theKey:String, theVal:String) {
// var keyDE's type is inferred from assignment
var keyDE = new DatabaseEntry(theKey.getBytes());

// var keyDE's type is inferred from assignment
var valDE = new DatabaseEntry(theVal.getBytes());

// var status' type is inferred from assignment
var status = theDb.put(txn, keyDE, valDE);
if (status <> OperationStatus.SUCCESS) {
throw status; // objects of any type can be thrown
}
}

operation get(theDb:Database, txn:Transaction, theKey:String) {
// var keyDE's type is inferred from assignment
var keyDE = DatabaseEntry { // empty constructor is invoked
data: theKey.getBytes() // java property is set declaratively
};

// var valDE's type is inferred from assignment
var valDE = DatabaseEntry;

// var status' type is inferred from assignment
var status = theDb.get(txn, keyDE, valDE, null);
if (status <> OperationStatus.SUCCESS) {
throw status; // objects of any type can be thrown
}

// operations get's type is inferred from its return value
return new String(valDE.getData());
}

If i have understood what JavaFX is i don't think this will make available JE on the Java ME platform or not immediately at least.

JE rely on J2SE 1.4 or higher and uses for example java.io.File and related classes, but these classes are not available in J2ME or at least in devices based on CLDC/MIDP.

This is one of the issues i have faced trying to use Berkeley DB Java Edition on BlackBerry device.

Charles Lamb:

David, you are correct that this will still not bring JE to a J2ME environment. There are a handful of things in the code which force reliance on Java 1.4: assertions, java.nio calls, and using of java.util.log classes.

Charles Lamb

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About This Entry

This page contains a single entry from the blog posted on May 8, 2007 3:32 PM.

The previous post in this blog was JavaOne and Oracle Develop.

The next post in this blog is JE, JCA, OC4J.

Many more can be found on the main index page or by looking through the archives.

Top Tags

Powered by
Movable Type and Oracle