JVM Drivers

Java logo Scala logo

Fauna’s open source JVM driver supports languages that run in the Java Virtual Machine. Currently, Java and Scala clients are implemented.

Current stable version

4.1.2

Repository

Features

Documentation

Javadocs and Scaladocs are hosted on GitHub:

Detailed documentation is available for these languages:

Dependencies

Shared

Java

  • Java 11

Scala

  • Scala 2.11.x

  • Scala 2.12.x

Install

Java

Download from the Maven central repository:

faunadb-java/pom.xml:
  <dependencies>
  ...
  <dependency>
    <groupId>com.faunadb</groupId>
    <artifactId>faunadb-java</artifactId>
    <version>4.1.2</version>
    <scope>compile</scope>
  </dependency>
  ...
</dependencies>

Scala

faunadb-scala/sbt:
libraryDependencies += ("com.faunadb" %% "faunadb-scala" % "4.1.2")

Usage

Java

import com.faunadb.client.FaunaClient;

import static com.faunadb.client.query.Language.*;

/**
 * This example connects to FaunaDB using the secret provided
 * and creates a new database named "my-first-database"
 */
public class Main {
    public static void main(String[] args) throws Exception {

        //Create an admin connection to FaunaDB.
        FaunaClient adminClient =
            FaunaClient.builder()
                .withSecret("put-your-key-secret-here")
                .withEndpoint("https://db.fauna.com/")
                // NOTE: Use the correct endpoint for your database's Region Group.
                .build();

        adminClient.query(
            CreateDatabase(
                Obj("name", Value("my-first-database"))
            )
        ).get();

        adminClient.close();
    }
}

For more usage details, see the supplemental Java driver documentation, and the Connections page.

Scala

import faunadb._
import faunadb.query._
import scala.concurrent._
import scala.concurrent.duration._

/**
  * This example connects to FaunaDB using the secret provided
  * and creates a new database named "my-first-database"
  */
object Main extends App {

  import ExecutionContext.Implicits._

  val client = FaunaClient(
    secret = "put-your-secret-here"
  )

  val result = client.query(
    CreateDatabase(
      Obj("name" -> "my-first-database")
    )
  )

  Await.result(result, Duration.Inf)

  client.close()
}

For more usage details, see the supplemental Scala driver documentation, and the Connections page.

Document streaming

Fauna supports document streaming, where changes to a streamed document are pushed to all clients subscribing to that document.

Java

The streaming API is built using the java.util.concurrent.Flow API, which enables users to establish flow-controlled components in which Publishers produce items consumed by one or more Subscribers, each managed by a Subscription.

The following examples assume that you have already created a FaunaClient. In the example, we are capturing the 4 first messages by manually binding a Subscriber.

// docRef is a reference to the document for which we want to stream
// updates. You can acquire a document reference with a query like the
// following, but it needs to work with the documents that you have.
// Value docRef = Ref(Collection("scoreboards"), "123")

Flow.Publisher<Value> valuePublisher = adminClient.stream(createdDoc).get();
CompletableFuture<List<Value>> capturedEvents = new CompletableFuture<>();

Flow.Subscriber<Value> valueSubscriber = new Flow.Subscriber<>() {
  Flow.Subscription subscription = null;
  ArrayList<Value> captured = new ArrayList<>();
  @Override
  public void onSubscribe(Flow.Subscription s) {
    subscription = s;
    subscription.request(1);
  }

  @Override
  public void onNext(Value v) {
    captured.add(v);
    if (captured.size() == 4) {
      capturedEvents.complete(captured);
      subscription.cancel();
    } else {
      subscription.request(1);
    }
  }

  @Override
  public void onError(Throwable throwable) {
     capturedEvents.completeExceptionally(throwable);
  }

  @Override
  public void onComplete() {
      capturedEvents.completeExceptionally(
          new IllegalStateException("not expecting the stream to complete")
      );
  }
};

// subscribe to publisher
valuePublisher.subscribe(valueSubscriber);

// blocking
List<Value> events = capturedEvents.get();

Scala

The following sections provide examples for managing streams with Flow or Monix, and assume that you have already created a FaunaClient.

Flow subscriber

It is possible to use the java.util.concurrent.Flow API directly by binding a Subscriber manually.

In the following example, we are capturing the 4 first messages:

import faunadb._
import faunadb.query._

// docRef is a reference to the document for which we want to stream
// updates. You can acquire a document reference with a query like the
// following, but it needs to work with the documents that you have.
// val docRef = Ref(Collection("scoreboards"), "123")

client.stream(docRef).flatMap { publisher =>
  // Promise to hold the final state
  val capturedEventsP = Promise[List[Value]]

  // Our manual Subscriber
  val valueSubscriber = new Flow.Subscriber[Value] {
    var subscription: Flow.Subscription = null
    val captured = new ConcurrentLinkedQueue[Value]

    override def onSubscribe(s: Flow.Subscription): Unit = {
      subscription = s
      subscription.request(1)
    }

    override def onNext(v: Value): Unit = {
      captured.add(v)
      if (captured.size() == 4) {
        capturedEventsP.success(captured.iterator().asScala.toList)
        subscription.cancel()
      } else {
        subscription.request(1)
      }
    }

    override def onError(t: Throwable): Unit =
      capturedEventsP.failure(t)

    override def onComplete(): Unit =
      capturedEventsP.failure(
        new IllegalStateException("not expecting the stream to complete")
      )
  }
  // subscribe to publisher
  publisher.subscribe(valueSubscriber)
  // wait for Future completion
  capturedEventsP.future
}

Monix

The reactive-streams standard offers a strong interoperability in the streaming ecosystem.

We can replicate the previous example using the Monix streaming library:

import faunadb._
import faunadb.query._
import monix.execution.Scheduler
import monix.reactive.Observable
import org.reactivestreams.{FlowAdapters, Publisher}

// docRef is a reference to the document for which we want to stream
// updates.  You can acquire a document reference with a query like the
// following, but it needs to work with the documents that you have.
// val docRef = Ref(Collection("scoreboards"), "123")

client.stream(docRef).flatMap { publisher =>
  val reactiveStreamsPublisher: Publisher[Value] = FlowAdapters.toPublisher(
    publisherValue
  )
  Observable.fromReactivePublisher(reactiveStreamsPublisher)
    .take(4) // 4 events
    .toListL
    .runToFuture(Scheduler.Implicits.global)
}

Next steps

Was this article helpful?

We're sorry to hear that.
Tell us how we can improve!
Visit Fauna's Discourse forums or email docs@fauna.com

Thank you for your feedback!