Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,422 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pg-java: A modern Java PostgreSQL driver

pg-java is a modern, PostgreSQL-specific database driver for the JVM.

Goals

  • PostgreSQL-first. The initial API is designed around PostgreSQL's wire protocol and feature set rather than the lowest-common-denominator constraints of JDBC. This lets us expose PostgreSQL's capabilities directly and idiomatically.
  • Eventually JDBC compliant. A JDBC-compliant layer is a long-term goal, but it will be built on top of the native API rather than dictating its shape. We do not want to be bound by the historical warts of JDBC from day one.
  • Modern Java. Written in plain Java targeting Java 21+. The driver is virtual-thread friendly: it uses simple, blocking-style code that does not pin carrier threads, so applications can run it on virtual threads without an async framework.
  • Streaming, pull-first. The core query primitive is a pull cursor that reads one row at a time and never buffers the whole result set; list/forEach/ map helpers are built on top.
  • Full featured. Over time the driver aims to support the breadth of PostgreSQL functionality (extended query protocol, COPY, LISTEN/NOTIFY, binary formats, SSL/TLS, SCRAM authentication with channel binding, and more). It does not ship its own connection pool; instead it provides the lifecycle primitives that external pools (and the JDBC DataSource) need.

Status

Under active development; pre-release and not yet published to Maven Central. The core driver is functional: it connects over plain TCP and TLS, authenticates (including SCRAM-SHA-256 with channel binding), and runs the simple and extended query protocols. A JDBC layer (java.sql.*, registered via java.sql.Driver) is implemented on top of it. The test suite includes integration tests that run against real PostgreSQL (and PgBouncer) via Testcontainers. APIs are still evolving and there are no compatibility guarantees yet. The implementation roadmap (phased, commit-by-commit) lives in docs/plans/overall.md, which also defines the "first useful JDBC release" minimum.

Connecting

The JDBC layer registers itself for the jdbc:pg: scheme (ADR-0015), and takes libpq-style parameters:

String url = "jdbc:pg://localhost:5432/appdb?user=app&sslmode=verify-full";
try (Connection connection = DriverManager.getConnection(url, "app", secret);
        PreparedStatement statement = connection.prepareStatement("select id from t where name = ?")) {
    statement.setString(1, "widget");
    try (ResultSet rows = statement.executeQuery()) {
        while (rows.next()) {
            System.out.println(rows.getLong(1));
        }
    }
}

It also answers to jdbc:postgresql: for ported applications, though which driver claims that scheme when real pgjdbc is also on the path is a decision of its own (ADR-0015). The PostgreSQL-native API underneath it is org.postgresql.client.core.PgConnections.connect(...), which returns a PgConnection and never mentions java.sql.

Project layout

pg-java is a multi-module Maven project. A parent (aggregator) POM ties the modules together. The modules are:

  • postgresql-client-protocol - Low-level PostgreSQL wire protocol: serializing and deserializing frontend/backend messages and data types. No connection or I/O policy lives here, just the on-the-wire encoding. Has no dependency on the other modules.
  • postgresql-client - The core driver. Connection management, authentication, TLS, the simple and extended query protocols, and the idiomatic PostgreSQL-first public API. Depends on postgresql-client-protocol.
  • postgresql-client-jdbc - The JDBC layer (java.sql.*) implemented on top of the core driver. Depends on postgresql-client. Registers a java.sql.Driver and provides Connection, PreparedStatement, ResultSet, DatabaseMetaData, DataSource, and XA support.
  • postgresql-client-pgjdbc-compat - A pgjdbc source-compatibility layer on top of postgresql-client-jdbc, exposing org.postgresql.Driver and common org.postgresql.* types. It is a migration aid, not a certified drop-in (yet): the exception types (PSQLException/ServerErrorMessage), the pgjdbc-identical driver name, and the vendor-extension ring (PGConnection, PGobject, geometric types, PGInterval, CopyManager, LargeObjectManager, PGSimpleDataSource) are in place, but some PGConnection methods are still stubbed and several functional paths await live-server verification. Treat the "drop-in" goal conservatively until that ring fully lands (see docs/follow-up.md, N4.3).
  • postgresql-client-bench - A driver-agnostic, pgbench-style JDBC benchmark that measures the driver, not the database. The driver under test (pg-java or pgjdbc) is supplied at runtime, never bundled. Build-only; not published. See postgresql-client-bench/README.md.
  • postgresql-client-bench-jmh - Server-free JMH micro-benchmarks for the codec, framing and buffer paths, where allocation (bytes/op) is the tracked number. See docs/benchmarks/ for the reference runs. Build-only; not published.
  • postgresql-client-coverage - Aggregates per-module JaCoCo coverage into one combined report. Build-only; not published.
  • postgresql-client-native-smoke - A GraalVM native-image smoke gate: it compiles the native-image metadata shipped by postgresql-client-jdbc and postgresql-client-pgjdbc-compat into a native binary and runs it, catching metadata regressions. Off by default (a plain build only compiles the probe); the native build runs under the native-smoke profile on a GraalVM JDK. Build-only; not published.

Requirements

  • Build/runtime: Java 21 or newer.
  • Build tool: Apache Maven. A Maven Wrapper (./mvnw) is checked in, so a separately installed Maven is optional; the wrapper downloads the pinned version on first use.

Building

./mvnw clean install

(or mvn clean install with a locally installed Maven).

Running tests

Unit tests run with plain Maven and need no Docker:

mvn test

Integration tests (Testcontainers against a real PostgreSQL, and PgBouncer where relevant) are gated behind the integration-tests profile so the default build stays Docker-free. They require a running Docker daemon:

mvn verify -Pintegration-tests

By default the integration tests run against postgres:17; pass -Dpg.it.image=<image> to test another server image, or use scripts/run-integration-matrix.sh to sweep several PostgreSQL versions.

To run the shared-server integration tests against an already-running PostgreSQL instead of Docker, set -Dpg.it.host:

mvn verify -Pintegration-tests -Dpg.it.host=localhost

The remaining coordinates default to port 5432 and postgres for the user, password, and database; override them with -Dpg.it.port, -Dpg.it.user, -Dpg.it.password, and -Dpg.it.database. The special-purpose harnesses (TLS, PgBouncer, auth, unix socket) provision their own containers and are skipped entirely when pg.it.host is set, so an external-server run never touches Docker.

Contributing

See AGENTS.md for project conventions, architecture notes, and guidance for both human and AI contributors.

Security

Please do not report vulnerabilities in a public issue. See SECURITY.md for the private disclosure process, and for the security-relevant defaults that are documented decisions rather than open findings.

License

pg-java is released under the PostgreSQL License, the same permissive license used by PostgreSQL itself.

The postgresql-client-pgjdbc-compat module deliberately mirrors the public org.postgresql.* API of pgjdbc, which is distributed under the BSD 2-Clause License and, like this project, is copyright the PostgreSQL Global Development Group. See that module's README.md.

About

A modern Java PostgreSQL driver

Resources

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages