Java SDK
The ParticleDB Java SDK is a JDBC 4.2 driver built natively against the PDB wire protocol. It is pure Java + Netty — no JNI, no pgjdbc dependency. The driver multiplexes (HTTP/2-style) over one TCP connection, with N concurrent streams per connection. Falls back to single-stream when talking to v1 servers.
Coordinates: ai.particledb:particledb-jdbc:1.0.0
For an in-depth JDBC reference and the full URL / TLS / pool option matrix, see the dedicated JDBC Driver page. This page is the quickstart.
Requirements
Section titled “Requirements”- Java 17+ (Java 11 is supported for compile + DDL/DML; Arrow result-row
decoding needs JDK 17 + the
--add-opensflags listed below) - Maven 3.9+ or Gradle 8+
- A running ParticleDB server (PDB wire on port 5440; the JDBC driver speaks PDB native wire, not PostgreSQL wire)
Install
Section titled “Install”Now on Maven Central — resolves from any default Maven or Gradle build with no extra repository declaration.
<dependencies> <dependency> <groupId>ai.particledb</groupId> <artifactId>particledb-jdbc</artifactId> <version>1.0.0</version> </dependency> <!-- Required for SELECT result-row decoding (Arrow IPC). --> <dependency> <groupId>org.apache.arrow</groupId> <artifactId>arrow-vector</artifactId> <version>15.0.2</version> </dependency> <dependency> <groupId>org.apache.arrow</groupId> <artifactId>arrow-memory-netty</artifactId> <version>15.0.2</version> </dependency></dependencies>dependencies { implementation("ai.particledb:particledb-jdbc:1.0.0") implementation("org.apache.arrow:arrow-vector:15.0.2") implementation("org.apache.arrow:arrow-memory-netty:15.0.2")}No build tool? Download the JAR directly and drop it on your classpath.
# Thin jar (~90 KB) — bring your own Netty + Arrow:curl -L -o particledb-jdbc-1.0.0.jar \ https://repo1.maven.org/maven2/ai/particledb/particledb-jdbc/1.0.0/particledb-jdbc-1.0.0.jar
# Or the uber-jar (~19 MB) — Netty bundled, just add Arrow:curl -L -o particledb-jdbc-1.0.0-all.jar \ https://repo1.maven.org/maven2/ai/particledb/particledb-jdbc/1.0.0/particledb-jdbc-1.0.0-all.jarThen run with the required JVM flags (Arrow Java reflects into ByteBuffer internals; Netty also benefits from explicit reflection):
java \ --add-opens=java.base/java.nio=ALL-UNNAMED \ --add-opens=java.base/sun.nio.ch=ALL-UNNAMED \ -Dio.netty.tryReflectionSetAccessible=true \ -cp particledb-jdbc-1.0.0-all.jar:/path/to/arrow-vector-15.0.2.jar:/path/to/arrow-memory-netty-15.0.2.jar:/path/to/app.jar \ com.example.AppJVM flags
Section titled “JVM flags”Apache Arrow Java needs reflective access to ByteBuffer internals. Add
to your JVM startup arguments:
--add-opens=java.base/java.nio=ALL-UNNAMED--add-opens=java.base/sun.nio.ch=ALL-UNNAMEDWithout these the driver will throw a clear, actionable error on the first SELECT result-set decode (it intentionally does NOT silently fall back to raw bytes).
Hello World
Section titled “Hello World”import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement;
public class Hello { public static void main(String[] args) throws Exception { Class.forName("org.particledb.Driver"); try (Connection c = DriverManager.getConnection( "jdbc:particledb://127.0.0.1:5440/default"); Statement s = c.createStatement(); ResultSet rs = s.executeQuery("SELECT 1")) { while (rs.next()) { System.out.println(rs.getInt(1)); } } }}CRUD round-trip
Section titled “CRUD round-trip”try (Connection c = DriverManager.getConnection( "jdbc:particledb://127.0.0.1:5440/default")) {
try (Statement s = c.createStatement()) { s.execute("CREATE TABLE users (id INT PRIMARY KEY, name TEXT, score DOUBLE)"); }
try (PreparedStatement ins = c.prepareStatement( "INSERT INTO users (id, name, score) VALUES (?,?,?)")) { ins.setInt(1, 1); ins.setString(2, "alice"); ins.setDouble(3, 92.5); ins.executeUpdate(); }
try (PreparedStatement sel = c.prepareStatement( "SELECT name, score FROM users WHERE id = ?")) { sel.setInt(1, 1); try (ResultSet rs = sel.executeQuery()) { while (rs.next()) { System.out.printf("name=%s score=%.2f%n", rs.getString("name"), rs.getDouble("score")); } } }}Connection pool (HikariCP)
Section titled “Connection pool (HikariCP)”The driver ships no built-in pool. Wrap it in HikariCP for fan-out:
HikariConfig cfg = new HikariConfig();cfg.setJdbcUrl("jdbc:particledb://127.0.0.1:5440/default");cfg.setMaximumPoolSize(10);cfg.setMinimumIdle(1);cfg.setConnectionTimeout(30_000);try (HikariDataSource ds = new HikariDataSource(cfg)) { try (Connection c = ds.getConnection()) { /* ... */ }}Note: the PDB wire transport itself already multiplexes streams per TCP connection, so a small pool (≤10) is usually sufficient.
Properties p = new Properties();p.setProperty("user", "app");p.setProperty("password", System.getenv("PDB_PASSWORD"));p.setProperty("sslMode", "verify-full"); // disable | require | verify-ca | verify-fullp.setProperty("sslRootCert", "/etc/ssl/internal-ca.crt");// p.setProperty("sslCert", "/run/secrets/pdb-client.crt"); // mTLS// p.setProperty("sslKey", "/run/secrets/pdb-client.key");try (Connection c = DriverManager.getConnection( "jdbc:particledb://db.example.com:5443/postgres", p)) { // ...}Modes match pgjdbc + the canonical Connection Options spec.
URL options
Section titled “URL options”jdbc:particledb://host:port/database?<options>| Option | Default | Description |
|---|---|---|
prepareThreshold | 5 | Executions before server-side prepare. |
preparedStatementCacheQueries | 256 | Client-side prepared cache size (entries). |
preparedStatementCacheSizeMiB | 5 | Client-side prepared cache cap (MiB). |
maxStreamsPerConn | 64 | Wire-v2 multiplex stream cap per TCP. |
sslMode | disable | TLS mode (disable / require / verify-ca / verify-full). |
preferUnixSocket | true | Try /tmp/.s.PDB.<port> first when local. |
connectTimeout | 30000 | TCP + handshake timeout (ms). |
PostgreSQL wire compatibility
Section titled “PostgreSQL wire compatibility”ParticleDB also exposes the PostgreSQL wire on port 5432. If you have an existing pgjdbc-based stack and don’t want to migrate to the native driver, you can keep using stock pgjdbc:
<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.7.4</version></dependency>Connection c = DriverManager.getConnection( "jdbc:postgresql://127.0.0.1:5432/mydb", "particledb", "");PG-wire supports the full pgjdbc feature set including server-side
prepared statements (via prepareThreshold), pipelined execution, and
interactive transactions with rollback-after-write semantics — useful if
your app relies on Connection.rollback() after a partial write.
Limitations
Section titled “Limitations”- The PDB native wire treats
BEGIN/COMMIT/ROLLBACKas batch markers, not full ACID brackets —Connection.rollback()after flushed writes will NOT undo them on PDB native wire. For interactive rollback, connect via PG wire (port 5432) using stock pgjdbc. - DataSource bean setters land on the native driver; JNDI registration for app-server deployments is on the v1.1 roadmap.
CallableStatementfor stored procedures is on the v1.1 roadmap.
Source + samples
Section titled “Source + samples”- Driver source:
sdk/java/jdbc/ - Runnable samples:
sdk/java/jdbc/samples/— HelloWorld, CrudRoundtrip, TransactionDemo, HikariCpDemo, PgJdbcCompat - CHANGELOG.md
Next steps
Section titled “Next steps”- JDBC Driver reference — deep dive on the URL, options, and architecture
- SQL Reference — full SQL syntax
- PostgreSQL Wire Protocol — for pgjdbc users