ObjectBox does not only work with Android projects, but also for plain Java (JVM) desktop apps running on Windows, Linux, and macOS. Just like on Android, ObjectBox stands for a super simple API and high performance. It’s designed for objects and outperforms other database and ORM solutions. Because it is an embedded database, ObjectBox runs in your apps’ process and needs no maintenance. Read on to learn how to create a Java project using ObjectBox. We believe it’s fairly easy. Please let us know your thoughts on it.
Because ObjectBox comes with a Gradle plugin, you use Gradle as a build system.
There is an experimental Maven plugin available. See the Java Maven example.
To get set up, in your project’s build.gradle
file, you apply the ObjectBox Gradle plugin. This must be done after applying the Java plugin.
This is how a Gradle build file using ObjectBox typically looks like:
buildscript {ext.objectboxVersion = '2.4.1'repositories {jcenter()}dependencies {classpath "io.objectbox:objectbox-gradle-plugin:$objectboxVersion"}}repositories {jcenter()}apply plugin: 'java'apply plugin: 'io.objectbox'
If you use IntelliJ IDEA, make sure to use 2019.1 or newer as it has improved Gradle support, like delegating build actions to Gradle.
In Gradle 5.1 or older annotation processor support is incomplete, so adding an annotation processor plugin (e.g. gradle-apt-plugin) is recommended:
buildscript {ext.objectboxVersion = '2.4.1'repositories {jcenter()maven { url "https://plugins.gradle.org/m2/" }}dependencies {classpath "net.ltgt.gradle:gradle-apt-plugin:0.20"classpath "io.objectbox:objectbox-gradle-plugin:$objectboxVersion"}}repositories {jcenter()}apply plugin: 'java'// Annotation processor plugin for better Gradle + IntelliJ support.apply plugin: 'net.ltgt.apt-idea'apply plugin: 'io.objectbox'
This set up is the main difference between the Android and plain Java desktop setup. Other than this, ObjectBox works the same across platforms.
Under the hood, ObjectBox is an object database running mostly in native code written in C/C++ for optimal performance (there’s no way to make this work as fast in plain Java). Thus, ObjectBox will load a native library: a “.dll” on Windows, a “.so” on Linux, and a “.dylib” on macOS. By default, the ObjectBox Gradle plugin adds a dependency to the native library matching your system. This means that your app is already set up to run on your system.
Note: on Windows you might have to install the Microsoft Visual C++ 2015 Redistributable (x64) packages to use the ObjectBox DLL.
Note that ObjectBox binaries are build for 64 bit systems for best performance. Talk to us if you require 32 bit support.
While the default build configuration ensures that your app runs on your development system, you may want to support all major platforms (Windows, Linux, macOS) when you distribute your app. For this, just add all platform dependencies to your project’s build.gradle
file like this:
dependencies {// Optional: include all native libraries for distributionimplementation "io.objectbox:objectbox-linux:$objectboxVersion"implementation "io.objectbox:objectbox-macos:$objectboxVersion"implementation "io.objectbox:objectbox-windows:$objectboxVersion"}
For reference, the following dependencies to the ObjectBox Java API and annotation processor are added by default by the ObjectBox Gradle plugin. Usually, there’s no need to set them up manually:
dependencies {// Added automatically by the plugin - just for reference.implementation "io.objectbox:objectbox-java:$objectboxVersion"annotationProcessor "io.objectbox:objectbox-processor:$objectboxVersion"}
By default, the ObjectBox model file is stored in module-name/objectbox-models/default.json
. You can change the file path and name by passing the objectbox.modelPath
argument to the ObjectBox annotation processor.
In your project’s build.gradle
file after the java plugin, add the necessary compiler argument:
tasks.withType(JavaCompile) {options.compilerArgs += [ "-Aobjectbox.modelPath=$projectDir/schemas/objectbox.json" ]}
1.5 or newer
By default the MyObjectBox class is generated in the same or a parent package of your entity classes. You can define a specific package by passing the objectbox.myObjectBoxPackage
argument to the ObjectBox annotation processor.
In your project’s build.gradle
file after the java plugin, add the necessary compiler argument:
tasks.withType(JavaCompile) {options.compilerArgs += [ "-Aobjectbox.modelPath=$projectDir/schemas/objectbox.json" ]}
You can enable debug output for the plugin and for the annotation processor if you encounter issues while setting up your project.
Just add the necessary options in your project’s build.gradle
file after the java and io.objectbox plugin
// enable debug output for pluginobjectbox {debug true}// enable debug output for annotation processortasks.withType(JavaCompile) {options.compilerArgs += [ "-Aobjectbox.debug=true" ]}
You must create at least one class annotated with @Entity to use ObjectBox. If you don’t know yet how to do this, learn here how to create and annotate entity classes.
The following code snippet shows how a simple entity class might look like:
@Entitypublic class Note {@Idpublic long id;public String text;public String comment;public Date date;public Note(long id, String text, String comment, Date date) {this.id = id;this.text = text;this.comment = comment;this.date = date;}public Note() {}}
To get a Box for saving your entities you need to build a BoxStore first. After creating your entity classes and building your project, e.g. by running gradlew build
, the class MyObjectBox will be generated. Use MyObjectBox.builder() to build your BoxStore.
This code snippet demonstrates a simple program that builds a BoxStore and saves a Note entity object:
public static void main(String[] args) {BoxStore store = MyObjectBox.builder().name("objectbox-notes-db").build();Box<Note> box = store.boxFor(Note.class);String text = args.length > 0 ? String.join(" ", args) : "No text given";box.put(new Note(text));System.out.println(box.count() + " notes in ObjectBox database:");for (Note note : box.getAll()) {System.out.println(note);}store.close();}
You can use the name(String) method of the builder to change the directory name your database files are stored in. See the BoxStoreBuilder documentation for more configuration options.
In your project’s build.gradle
file, add the JUnit testing framework to your test dependencies:
dependencies {testCompile 'junit:junit:4.12'}
You create your unit test classes as usual under module-name/src/test/java/
. To use ObjectBox in your test methods you need to build a BoxStore instance using the generated MyObjectBox class of your project. You can use the directory(File) method on the BoxStore builder to ensure the test database is stored in a specific folder on your machine. To start with a clean database for each test you can delete the existing database using BoxStore.deleteAllFiles(File).
The following example shows how you could implement a unit test class that uses ObjectBox:
public class NoteTest {private File boxStoreDir;private BoxStore store;@Beforepublic void setUp() throws IOException {// store the database in the systems temporary files folderFile tempFile = File.createTempFile("object-store-test", "");// ensure file does not exist so builder creates a directory insteadtempFile.delete();boxStoreDir = tempFile;store = MyObjectBox.builder()// add directory flag to change where ObjectBox puts its database files.directory(boxStoreDir)// optional: add debug flags for more detailed ObjectBox log output.debugFlags(DebugFlags.LOG_QUERIES | DebugFlags.LOG_QUERY_PARAMETERS).build();}@Afterpublic void tearDown() throws Exception {if (store != null) {store.close();store.deleteAllFiles();}}@Testpublic void testPutAndGet() {Box<Note> box = store.boxFor(Note.class);assertEquals(...);}}
To help diagnose issues you can enable log output for ObjectBox actions, such as queries, by specifying one or more debug flags when building BoxStore.