An Oracle White Paper October 2011

Databases in Embedded Applications

With an Oracle Berkeley Example

Databases in Embedded Applications

Introduction

This white paper describes embedded database use in general, and specifically how to setup and use Berkeley Database with Oracle Java Micro Edition Embedded Client on a BeagleBoard device.

Database Support in Oracle Java Micro Edition Embedded Client

Oracle Java Micro Edition Embedded Client is a Java virtual machine and libraries for supporting embedded device applications. Such applications run on hardware whose resources fall between desktop (the domain of Java Standard Edition) and mobile (the domain of Oracle Java Micro Edition Wireless Client). Typical applications are televisions, Blu-ray Disc players, and set-top boxes; printers, IP phones, ebook readers, and smart utility meters. See this page for more information: http://www.oracle.com/technetwork/java/embedded/overview/getstar ted/index.html.

Databases are useful in many embedded devices, where they can store and retrieve data as disparate as electricity usage and television programming guides. The standard Java API for database access is defined by the Java Database Connectivity (JDBC) specification, JSR 54 (and revisions). Oracle Java Micro Edition Embedded Client supports the JSR 169 subset of JDBC, which matches the limited resources of embedded devices. For details of JSR 169, see http://jcp.org/aboutJava/communityprocess/final/jsr169/index.html. (For readers who are familiar with the full JDBC API, the main feature missing in JSR 169 is the DriverManager class.)

The following diagram shows how an application calls methods in the JSR 169 API, and a JSR 169 implementation translates the calls into database operations, returning results back to the application.

Databases in Embedded Applications

Figure 1. Flow of Embedded Application Database Calls Notice that the JSR 169 API insulates an application from database particulars. That insulation makes changing databases, or deploying an application to a device with a different database, very straightforward. In most cases, not even recompiling is required. Although portability is a great advantage, JSR 169’s masking of database differences has a drawback as well; it does not provide Java access to all the features of any database, including Berkeley DB.

JSR 169 is very flexible. It presents a uniform interface to applications, yet it can accommodate almost any database. It further defines two database interaction models: sending SQL statements to the database and invoking methods in classes that represent database constructs such as rows. Database vendors are the best source of information on how a particular database works with JSR 169 and with a particular platform.

JSR 169’s flexibility and adaptability presents a challenge to describing how to set it up and use it Oracle Java Micro Edition Embedded Client. Every database will be set up differently, and, for a given database, every OS/CPU platform might be set up differently. Separately, after the setup has been completed, some

Databases in Embedded Applications

developers will choose to interact with the database by SQL statements, whereas others will choose the object-oriented technique.

This white paper responds to the challenge with an example that gives the flavor of using JSR 169 by describing:

• Setting up Oracle’s Berkeley DB on a BeagleBoard platform running Oracle Java Micro Edition Embedded Client release 1.0. Setup for other platforms differs in detail, but this example is representative.

• Writing a simple example that sends SQL statements to the database via the JSR 169 API.

About Berkeley Database

Oracle Berkeley Database is a compact and flexible database, written in C and well-suited to mobile and embedded applications. Its simplicity and power have made it very popular. For more information on Berkeley DB, start with this link: http://www.oracle.com/technetwork/database/berkeleydb/overview/i ndex.html.

About the BeagleBoard

The BeagleBoard (http://beagleboard.org) is a popular low-cost, low-power single board computer, typical of those used in embedded applications. It is supported by version 1.0 of Oracle Java Micro Edition Embedded Client. The BeagleBoard’s ARM processor is different from the x86 CPU that powers the PCs that most developers use to write . Unlike Java application code, the Berkeley Database’s C source code must be cross-compiled to produce ARM machine instructions. Cross compilation is also typical for low-level code in embedded applications. For all of these reasons, the BeagleBoard makes a good demonstration platform for this white paper.

Databases in Embedded Applications

Acquiring and Building Berkeley Database

Berkeley DB is provided as a zipped collection of source files. To use it with Oracle Java Micro Edition Embedded Client, you download, configure, and build it as described in this section.

Downloading Downloading Berkeley Database requires a free Oracle account. You can create one when you are asked to log in. To download the Berkeley Database source bundle, follow these instructions: 1. Create a directory in which to download and build the database, and make it the current directory.

2. In a web browser, go to this site, logging in if required: http://www.oracle.com/technetwork/database/berkeleydb/downloa ds/index.html 3. Download the latest Berkeley DB 11gR2 gzip format to the current directory. You can choose a version with or without encryption. This white paper uses Berkeley DB 5.2.31.tar.gz.

4. Unzip the bundle, creating a tar file: % gunzip *.gz

5. Untar the files: % tar oxvf *.tar For an overview of the Berkeley Database documentation, open docs/index.html.

Configuring and Building the Database On the PC, configure the Berkeley Database for the Oracle Java Wireless Embedded Client, then build it:

1. Make build_unix the current directory.

Databases in Embedded Applications

2. Set environment variables used by the configure command:

% export JAVAC_FLAGS="-g -source 1.4 -target 1.4 -Xbootclasspath:$OJEC_ HOME/lib/btclasses.zip:$OJEC_HOME/lib/foundation.jar:$OJEC_HOME/lib/jdbc.jar " % export CFLAGS="-fPIC -fpic -DPIC -Os -fno-strict-aliasing -fno-common - Wall -W -Wno-unused-parameter -Wno-sign-compare" 3. Configure the build:

% ../dist/configure \ --enable-jdbc \ --disable-largefile \ --disable-hash \ --disable-queue \ --disable-replication \ --disable-verify \ --enable-shared \ --disable-static \ --with-cryptography=no \ --build=i686-pc-linux-gnu \ --host=arm-none-linux-gnueabi \ cross_compiling=yes \ CC=path-to-cross-compiler/arm-none-linux-gnue abi-gcc \ --prefix=deviceDBFiles

Here are definitions of some of the important arguments:

ñ --build: The PC that runs the

ñ --host: The target device

ñ --prefix: Directory to hold the database files that must be copied to the device

4. Build: % make

5. Gather the device database files into the --prefix directory: % make install

Databases in Embedded Applications

Preparing the Device

Running an application that uses the Berkeley Database requires the presence of database, Oracle Java Micro Edition Embedded Client, and Java Developer’s Kit (JDK) files on the device. This section assumes that the device already has the JDK and that the environment variable JDK_HOME points to it.

1. Copy the device database files from the --prefix directory to the device. There are several ways to do the copy, one of them is by means of the BeagleBoard SD card in an SD card reader connected by USB to the PC, for example:

% tar cf deviceDBFiles.tar deviceDBFiles/include deviceDBFiles/bin deviceDBFiles/jar deviceDBFiles/lib

2. Move the SD card to the BeagleBoard and untar the database files in the permanent file system: % tar oxvf *.tar path-to-deviceDBFiles

3. Copy the ojec1.1/bin/ and lib/ directories from the PC to the BeagleBoard device, using the SD card or method of your choice.

4. Set environment variables used by the Java compiler and the Oracle Java Micro Edition Embedded Client application launcher:

% export BDB_HOME="path-to-deviceDBFiles" % export OJEC_HOME="path-to-ojec-top-directory"

Databases in Embedded Applications

Compiling and Launching a Database Application

Most real application developers use an integrated development environment running on a PC. They test with a device emulator on the PC or a network connection to a physical device. For simplicity, the following command line example shows how the Java compiler and the application launcher use the database and Oracle Java Micro Edition Embedded Client directories denoted by BDB_HOME and OJEC_HOME, respectively:

1. Compile your application: % cd your-Database-App-Directory % $JDK_HOME/bin/javac -target 1.4 -source 1.4 \ -bootclasspath \ $OJEC_HOME/btclasses.zip:$OJEC_HOME/lib/jdbc.jar:$BDB_HOME/jar/.jar \ *.java

2. Launch your application: % cd $OJEC_HOME

Writing Database Applications

If you have written SQL statements, you already know most of what you need to know to create a database application with Oracle Java Micro Edition Embedded Client. In fact, behind the JSR 169 API, the database is processing SQLite statements that your application composes. Because the Java virtual machine insulates the application from hardware and operating system differences, and the JSR 169 insulates the application from database differences, applications are easily ported to new devices and databases.

Overview Here is the essential model of an Oracle Java Micro Edition Embedded Client database application:

Databases in Embedded Applications

ñ Establish a Connection to the database, which is analogous to a session.

ñ Compose Statements of SQLite strings, such as create, insert, update, and select.

ñ Call a Statement method that passes the string to the database. ñ If applicable, process the data returned by the database.

ñ Close Statements and Connections when they are no longer needed.

Three Simple Examples The simple examples in this section apply to any database that has been set up for JSR 169 using the SQLite statement interaction model.

Creating a Table The following code shows how to create a simple table with JSR 169. The essential ideas are:

ñ Create a Connection to the database (a session) with a jdbc URL.

ñ In the connection, create a Statement object.

ñ Call the Statement’s execute() method, passing a string containing the SQLite statement for creating the table. import java..*; public class CreateCoffees {

public static void main(String args[]) {

String url = "jdbc:sqlite:/myDataSource"; Connection con; String createString; createString = "create table COFFEES " +

Databases in Embedded Applications

"(COF_NAME varchar(32), " + "SUP_ID int, " + "PRICE float, " + "SALES int, " + "TOTAL int)"; Statement stmt;

try { con = new SQLite.JDBCDataSource(url).getConnection(); stmt = con.createStatement(); stmt.executeUpdate(createString); stmt.close(); con.close();

} catch (SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); } } }

Inserting Rows Inserting a row in a table is much like creating a table. You create a connection to the database, then fabricate and execute SQLite insert statements. import java.sql.*; public class InsertCoffees {

public static void main(String args[]) {

String url = "jdbc:sqlite:/myDataSource"; Connection con; Statement stmt;

try {

Databases in Embedded Applications

con = new SQLite.JDBCDataSource(url).getConnection();

stmt = con.createStatement();

stmt.executeUpdate("insert into COFFEES " + "values('Colombian', 00101, 7.99, 0, 0)");

stmt.executeUpdate("insert into COFFEES " + "values('French_Roast', 00049, 8.99, 0, 0)");

stmt.executeUpdate("insert into COFFEES " + "values('Espresso', 00150, 9.99, 0, 0)");

stmt.executeUpdate("insert into COFFEES " + "values('Colombian_Decaf', 00101, 8.99, 0, 0)");

stmt.close(); con.close();

} catch (SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); } } }

Selecting Data Selecting data from a table follows the same pattern of connecting and executing an SQLite select statement. Individual data items are then pulled from the result and printed. import java.sql.*; public class SelectCoffees {

public static void main(String args[]) {

String url = "jdbc:sqlite:/myDataSource"; Connection con;

Databases in Embedded Applications

Statement stmt; String query = "select COF_NAME, PRICE from COFFEES where PRICE=’8.99’";

try {

con = new SQLite.JDBCDataSource(url).getConnection();

stmt = con.createStatement();

ResultSet rs = stmt.executeQuery(query);

System.out.println("Coffee Break Coffees and Prices:"); while (rs.next()) { String s = rs.getString("COF_NAME"); float f = rs.getFloat("PRICE"); System.out.println(s + " " + f); }

stmt.close(); con.close();

} catch (SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); } } }

Conclusion

Using a database in an Oracle Java Micro Edition Embedded Client application is straightforward to anyone who has database experience. JSR169’s deliberately generic design has advantages and disadvantages. The advantages are two programming models and accommodation of almost any database. The disadvantage can be somewhat complicated setup. Once the setup is working, however, Oracle Java Micro Edition Embedded Client database applications are highly portable.

[*20. Header_2] Title of White Paper Here

Databases in Embedded Applications Copyright © 2011, Oracle and/or its affiliates. All rights reserved. This document is provided for information purposes only and the October 2011 contents hereof are subject to change without notice. This document is not warranted to be error-free, nor subject to any other Author: Hinkmond Wong warranties or conditions, whether expressed orally or implied in law, including implied warranties and conditions of merchantability or Contributing Authors: Riaz Aimindi, Darryl fitness for a particular purpose. We specifically disclaim any liability with respect to this document and no contractual obligations are Mocek, Nikolay Yatsenko formed either directly or indirectly by this document. This document may not be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without our prior written permission. World Headquarters Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. 500 Oracle Parkway Redwood Shores, CA 94065 Intel and Intel Xeon are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are used under license and U.S.A. are trademarks or registered trademarks of SPARC International, Inc. AMD, Opteron, the AMD logo, and the AMD Opteron logo are Worldwide Inquiries: trademarks or registered trademarks of Advanced Micro Devices. is a registered trademark licensed through X/Open Phone: +1.650.506.7000 Company, Ltd. 0611 Fax: +1.650.506.7200 oracle.com

13