Core+ Java Client
Deephaven's Core+ Java client provides communication to the PQ controller as well as the Authentication server. This communication enables you to create new workers, discover the address of existing workers, and access the internal database via a session.
The underlying session object is a wrapper around the Deephaven Community Core Java client. Thus, all table operations and Community Core functionalities are inherited from the Community client API.
Note
This guide focuses on Core+ specific features like Persistent Query management, cluster connections, and enterprise authentication. For table operations, listeners, and general Java client usage, see the Community Core Java client guide.
Setup
Setup for the Core+ Java client is typically done through Gradle. For instructions, see Core+ Java client setup.
While there are multiple ways to set up the client with tools other than Gradle, this guide uses Gradle for its simplicity and interoperability.
Note
Maven Core+ Java Client Example provides a full project example using the Barrage Java Client with Maven as an alternative to using Gradle.
Get started
After completing setup, you must configure Deephaven to load properties from your Deephaven server's URL. This typically uses port 8000 when your system is configured with Envoy or port 8123 without Envoy. You must set the properties URL before using any other Deephaven classes; otherwise, static fields in classes will fail to initialize.
There are two ways you can interact with data via the Core+ Java client:
client-barrage: Unlocks the full power of the ticking Deephaven engine through Deephaven's Barrage extension. Supports live, ticking table subscriptions. Requires Java 11 or later.client-flight: Provides the ability to get static snapshots of tables using the Apache Arrow Flight protocol. Does not support live updates. Requires Java 8 or later.
Tip
Which should I use? Use client-barrage if you need live, ticking data or are building applications that react to real-time updates. Use client-flight only if you need Java 8 compatibility or only require static snapshots.
Next, create a session that loads the connection configuration from the URL. You can use either client-barrage or client-flight:
Then, authenticate with the server using a username and password:
Alternatively, you can use a private key for better security:
Now you can connect to an existing PQ. The session object provides basic methods for interacting with tables and also gives you access to the underlying SessionImpl for direct worker interaction.
Alternatively, you could create a new temporary Persistent Query to host your worker:
Alternatively, you could create a new temporary Persistent Query to host your worker:
For more precise control over Persistent Query options, you can create a configuration object builder directly:
The following examples are self-contained Java clients that connect to a running Persistent Query and table.
The Gradle setup instructions provided here include the required parameters to run the included examples. A Core+ Persistent Query should be running that creates a table (for example, with db.liveTable), and the Java files should be updated to use that PQ's name as well as a valid username/password or a keyfile.
Cluster connections and PQ management
For programmatic Persistent Query management and cluster-level operations, create a DeephavenClusterConnection:
Check PQ status
Query PQ information and status:
Start or restart a PQ
Programmatically control PQ lifecycle:
Monitor PQ state changes
Subscribe to PQ state updates:
Manipulate tables
You can run table operations and queries on either the server or the client. Depending on your needs, you can run queries directly on the server or distribute workloads across multiple clients. The Core+ Java client supports both approaches.
Manipulate tables on the server
To fetch and manipulate tables from the query, create a TableSpec object using one of the session's four root methods, then subscribe to it using the methods below.
| Method | Description |
|---|---|
catalogTable | A table containing the full catalog of available database tables. |
scopeTable | A named table in the query scope. |
historicalTable | A table from the historical table space. |
liveTable | A table from the intraday table space. |
For example:
The TableSpec does not send any data to the client. The following list includes just a few table operations that can be applied to a TableSpec:
The example above runs a where on the TestTable in the worker directly.
When the subscribeTo or snapshotOf methods are called, then the server performs the operations described in the TableSpec and returns the resultant data.
When streamOf is called, the server performs the operations described in the TableSpec and returns the resultant data as a FlightStream.
This snippet produces a FlightStream, which is a static snapshot of the source table.
Manipulate tables in the client
The Table is a client-side object that contains a copy of all data from the server. The Barrage protocol replicates consistent updates to the client. The engine runs locally within the client, allowing table operations like where, sort, or update to execute outside the server, distributing workloads across multiple machines.
For details on table listeners and client-side operations, see the Community Core Java client guide.
Execute scripts on the server
You can also execute script code blocks on the worker using the executeCode method. After the script runs, retrieve its results using the method appropriate for your client:
Note
The executeCode method permits arbitrary code execution and is unstructured and unvalidated. Use TableSpec methods where possible.
Access database tables
Note
The following examples use client-barrage. For client-flight, replace snapshotOf and subscribeTo calls with streamOf, which returns a FlightStream instead of a Table.
Use liveTable to access intraday data and historicalTable to access historical data. You can use snapshot or subscribe on either type of data:
Cleanup
Connections, sessions, and tables fetched from a Deephaven query all consume resources and must be properly closed when you finish using them.
Every Table, Session, and SessionFactory has a close method that you should call when finished with each object.
Using try-finally
Always close sessions when done to free resources:
Explicit cleanup pattern for Barrage subscriptions
Complete example
Here's a complete end-to-end example:
Best practices
Connection pooling
Reuse session factories across your application:
Performance
Choose the right approach for your use case:
- Server-side operations: Use
TableSpecoperations for heavy filtering, joins, and aggregations. - Client-side operations: Distribute light operations across multiple clients.
- Snapshots vs. subscriptions: Use
snapshotOffor static data andsubscribeTofor live updates. - Resource cleanup: Always close tables and sessions to free memory.
Access the full Deephaven Community API
If you want more sophisticated interactions with the query worker, you may retrieve the underlying SessionImpl from the session using the .session method.
See the Community Documentation and Java client guide for more details on table listeners, advanced operations, and client-side table manipulation.