What's new in 3.0 Architecture Modules Native drivers Code lab Migrate from 2.x Quickstart Blog Licensing GitHub ↗
NEW · 3.0.0 Native Panama drivers for 5 databases. JDBC is gone.

Java, without the middlemen.

Axiom 3 takes your bytes from the socket to the database and back as immutable data. No JDBC, no connection pool, no ORM, no reflection, and no third-party JARs. It's plain Java 26 calling libpq, OCI and ODBC directly through Project Panama.


            
          
Zero reflection Only java.* imports Immutable by default On Maven Central
PQexecParamsbound out-of-band · OID typed
Result.successno exception escaped
AccountQuery.javacompiles on Java 26
Native drivers · no JDBC
  • PostgreSQL libpq
  • MySQL libmysqlclient
  • Oracle OCI
  • SQLite sqlite3
  • SQL Server ODBC
0
production modules, released in lock-step
0
databases reached natively via Panama
0
third-party runtime dependencies
0
uses of java.lang.reflect
0
Java baseline, with modern preview APIs
~0k
lines of auditable Java across the stack
What's new in 3.0

The biggest release yet.
The smallest dependency tree ever.

Axiom 3.0 replaces the JDBC and Vert.x engines with five native drivers, moves parsing off-heap onto MemorySegment, and splits the forensic flight recorder out into its own module.

Native drivers through Project Panama

Every driver binds the vendor's own C client with the Foreign Function & Memory API. Connections are created per wield(..) inside a confined Arena, and they're closed and freed before the call returns. Nothing is pooled, and nothing leaks between calls.

your code→JDBC→pool→Panama downcall→libpq · OCI · ODBC→database
postgresqlmysqloraclesqlitesqlserver

axiom-telemetry

A rolling black-box recorder. When an operation fails, the failure arrives with a snapshot of everything that succeeded just before it.

new modulelock-free

Off-heap parsing

JsonParser, CsvRowParser, AxiomDopParser and SchemaGuard all read a MemorySegment directly. They can read files memory-mapped from disk, without first copying them into a byte[].

Contract-verified bulk ingest

Before a single CSV row is sent, Hammer checks your declared headers and types against the live catalog and reports every mismatch at once.

Scoped native memory

BoundScope binds a confined arena to each call through ScopedValue. It has no thread-locals and no finalizers, and it runs safely on virtual threads.

Typed binds, native syntax

You write :java.name once. Each driver rewrites it to the engine's own placeholder ($1, :1 or ?) and binds it out-of-band with an explicit type.

dynamicQuery("… WHERE status = :java.status LIMIT :java.limit")
  .to("ACTIVE").bind(PostgresType.TEXT)
  .to(10).bind(PostgresType.INT8)

Ten modules, one version

The stack has five core modules and five drivers, all at 3.0.0 and all signed and published together. Each is a plain JAR with its own JPMS automatic module name, and you import only what you use.

axiom←sovereign←language·spec←warp-*-driver·telemetry
Architecture

Five layers. Every edge is explicit.

Each module depends only on the layers below it, and the whole graph sits on axiom, which itself depends on nothing but the JDK. Select a module to see its dependency chain, packages and coordinates.

Layer 4Native drivers
Layer 3Validation
Layer 2Contracts & grammar
Layer 1Foundation
Layer 0Platform
JDK 26java.base · java.lang.foreign
Anatomy of a request

From socket to SQL and back, in six honest steps.

This is a real handler from the 3.0 reference strike. Scroll through it: every step is a function call you can read, and there's no framework hiding the rest.

01

Bytes arrive

The request body becomes a MemorySegment. Parsers read it in place, without building intermediate Strings.

java.lang.foreign
02

Parse and guard the perimeter

JsonParser builds a frozen PersistentMap, and SchemaGuard validates it against a cached .axiom schema. The first violation comes back as a Result, with its exact path.

axiom-spec · axiom-language
03

Extract typed values at the edge

The data stays untyped inside. Types are asserted only where you need them, with targetKey(..).toStringVal().

axiom
04

Wield a native connection

wield binds a confined arena, opens one libpq connection, runs your lambda and always disconnects, whether it succeeds or fails.

axiom-warp-postgresql-driver
05

Bind out-of-band with explicit types

Each :java.name becomes $n and goes through PQexecParams with an explicit OID. Values never touch the SQL text.

PostgresType
06

Emit immutable rows

Rows come back as a PersistentList<PersistentMap>. map shapes the response, and JsonEmitter writes it out. Failures stay values the whole way.

axiom · axiom-spec
AccountQueryExecutor.java
bytesJsonParserSchemaGuardtargetKeywieldPQexecParamsResult
The catalog

Ten modules. Import exactly what you need.

Every artifact lives under com.ensemblu at version 3.0.0, ships with sources and Javadoc, and is GPG-signed on Maven Central.

Native drivers

One shape. Five engines.

Every driver exposes the same Executioner: wield, transaction, shot, dynamicQuery and fromFile. Under the hood, each one does what's idiomatic for its engine. Pick an engine to see exactly how.

PostgreSQL

com.ensemblu:axiom-warp-postgresql-driver:3.0.0
    EngineNative clientPlaceholder → bindBulk ingestTransactionsProvisioning chainType catalog
    PostgreSQLlibpq$n · PQexecParams + OIDCOPY … FROM STDIN streamBEGIN / COMMIT / ROLLBACKhost → port → dbName → user → password?PostgresType
    MySQLlibmysqlclient? · escaped literal splicebatched multi-row INSERTBEGIN / COMMIT / ROLLBACKhost → port → dbName → user → password?MySqlType
    OracleOCI (Instant Client):n · OCIBindByPosprepared INSERT, bind-once buffersOCITransCommit / Rollbackhost → port → serviceName → user → password?OracleType
    SQLitesqlite3positional · sqlite3_bind_*prepare once, step / reset per rowBEGIN / COMMIT / ROLLBACKpathSqliteType
    SQL ServerODBC + MS ODBC 18? · SQLBindParameterprepared INSERT, bind-once buffersBEGIN TRANSACTION / COMMIThost → port → dbName → user → password?SqlServerType
    Code lab

    The API, one recipe at a time.

    Every snippet below is written against the 3.0.0 sources: real class names, real method chains, nothing invented for the brochure.

    Why Axiom exists

    Seven failure modes, removed at the root.

    Each of these is a problem that enterprise Java stacks accept as normal. Open one to see what goes wrong, what Axiom 3 does instead, and which module does it.

    Your dependency tree

    Count what you ship.

    Here's the same feature (a validated JSON endpoint that queries PostgreSQL) on a typical stack and on Axiom 3. The 2.x strike itself shipped HikariCP, slf4j and the PostgreSQL JDBC driver. The 3.0 strike ships none of them.

    A typical stack

    Framework + ORM + pool + JDBC + JSON binder + validator

    ✕ web framework + DI container classpath scanning ✕ ORM + bytecode proxies reflection, dirty checking ✕ connection pool tuning knobs, leaks ✕ JDBC driver type inference ✕ reflective JSON binder mutable DTOs ✕ annotation validator runtime metadata ✕ logging façade + binding … plus their transitive dependencies
    Third-party JARs on the classpathdozens

    Axiom 3.0

    The complete runtime graph of the reference strike

    ✓ com.ensemblu:axiom-warp-postgresql-driver └─ ✓ com.ensemblu:axiom-spec └─ ✓ com.ensemblu:axiom ✓ com.ensemblu:axiom-language └─ ✓ com.ensemblu:axiom-sovereign └─ ✓ com.ensemblu:axiom ✓ JDK 26 (jdk.httpserver, java.lang.foreign) + the vendor's native client library
    Third-party JARs on the classpath0
    ConcernAxiom 2.xAxiom 3.0
    Database accessaxiom-warp-jdbc (JDBC + your pool) and axiom-warp-reactive (Vert.x 5)Five native drivers over Panama, with no JDBC and no pool
    EnginesPostgreSQL-centric, with dialect translation on the reactive pathPostgreSQL, MySQL, Oracle, SQLite and SQL Server, each idiomatic
    Parser inputbyte[]MemorySegment (heap, native or memory-mapped)
    Parameter typingAxiomProtocol contract map + ::castOne explicit engine type per bind: .to(v).bind(PostgresType.X)
    Parallel readswarp.parallel(tasks)One wield per virtual thread, with independent connections
    Bulk ingestwarp.ingest().fromFile(..)fromFile(..).withDataTypes(..), verified against the catalog first
    Failure forensicswithHistory(..) inside the reactive engineStandalone axiom-telemetry that works with any Result
    axiom-spec scopeParsers + DB contracts, binders, registriesParsers and the emitter only. DB contracts moved into each driver
    Published modules610
    Upgrade guide

    2.x → 3.0, side by side.

    3.0 is a SemVer-major release. Here are the eight changes you'll actually touch, each shown before and after. The full breaking-change inventory is in the 3.0 changelog.

    − 2.x
    + 3.0
    Quickstart

    Query PostgreSQL natively in four steps.

    Add the driver

    It brings in axiom-spec and axiom transitively.

    <dependency>
      <groupId>com.ensemblu</groupId>
      <artifactId>axiom-warp-postgresql-driver</artifactId>
      <version>3.0.0</version>
    </dependency>

    Describe the perimeter

    Put a plain properties file on the classpath. There's no JDBC URL and no pool to tune.

    engine.host=localhost
    engine.port=5432
    engine.dbname=axiom_demo
    engine.user=axiom_commander
    engine.password=strike_hard

    Provision the executioner

    The curried chain makes a missing step a compile error, and a bad value fails at boot.

    var pg = PostgreSQL
      .connect(file("database.properties"))
      .requiredHost().requiredPort()
      .requiredDbName().requiredUser()
      .optionalPassword()
      .getPostgreSqlDriverOrThrow();

    Wield a query

    You get a Result of immutable rows. Nothing throws unless you ask it to.

    var rows = pg.wield(conn ->
      pg.dynamicQuery(
        "SELECT * FROM accounts WHERE status = :java.s")
      .to("ACTIVE").bind(PostgresType.TEXT)
      .execute(conn));
    Runtime flags. Axiom 3 compiles against Java 26 preview APIs, so run with --enable-preview. Add --enable-native-access=ALL-UNNAMED to silence restricted-method warnings for the Panama downcalls. The vendor client (libpq, libmysqlclient, Oracle Instant Client, sqlite3 or an ODBC driver) has to be findable by your OS loader. On Windows, that means it's on PATH.
    Engineering notes

    Read the reasoning, not just the release.

    Long-form articles on design decisions, migration paths and the opinions behind them.

    Licensing

    Evaluate freely. Ship with a contract.

    Axiom is published under the Limited Commercial License. You can pull, read, test and build with it at no cost. Running it in production, or for any commercial purpose, requires a paid annual agreement.

    Free

    Evaluation & learning

    $0
    • All 10 modules from Maven Central
    • Full source and Javadoc JARs
    • Evaluation, education and testing
    • Non-commercial development
    • Production or revenue-supporting use
    Start evaluating
    Annual

    Commercial license

    Contractper year
    • Production and commercial use of Axiom 3
    • Signed Commercial Enterprise License Agreement
    • Direct line to the core architect
    • Covers every module in the 3.0 stack
    Request a license
    Custom

    Engineering services

    Scopedby engagement
    • Private or air-gapped deployments
    • Custom off-heap protocol drivers
    • Data-oriented pipeline design
    • Architecture audits
    See services
    FAQ

    Questions engineers actually ask.

    Why drop JDBC entirely?

    JDBC is an abstraction over vendor wire protocols, and it brings type inference, driver-specific quirks and, in practice, a pool and its tuning along with it. Since Project Panama is final, Java can call the vendor's own C client directly. So that's what Axiom 3 does: one explicit downcall per operation, with typed parameters and nothing in between.

    No connection pool? Isn't that slow?

    Each wield(..) opens a dedicated native connection and closes it when the call returns. That makes resource ownership trivial, with no leaked connections and no shared state, and it fits virtual threads. Put batches, transactions and related reads inside a single wield so they share one session. For very high request rates, measure against your own latency budget; it's an explicit trade-off, and it's documented as one.

    Which Java version do I need?

    Java 26. Axiom uses java.lang.foreign, ScopedValue and other modern APIs, and it's compiled with --enable-preview, so your application must run with --enable-preview too.

    Do I need the native client libraries installed?

    Yes. That's the point: Axiom ships no wire-protocol reimplementation. Install libpq (PostgreSQL), libmysqlclient (MySQL), Oracle Instant Client, sqlite3, or the Microsoft ODBC Driver 18 for SQL Server, and make sure the OS loader can find it.

    Can I still use Axiom without a database?

    Absolutely. axiom on its own gives you persistent collections, Result, guards, navigation, config and effects. Add axiom-spec for JSON/CSV, axiom-language for schema validation, and axiom-telemetry for failure forensics. None of these touch a database.

    What happened to axiom-warp-jdbc and axiom-warp-reactive?

    They're retired in 3.0. The native drivers replace the JDBC engine, plain virtual threads replace the Vert.x engine's concurrency, and the reactive engine's forensic history now lives in axiom-telemetry. The 2.x artifacts stay on Maven Central. See the migration guide above.

    Is it safe against SQL injection?

    PostgreSQL, Oracle, SQLite and SQL Server send values out-of-band as typed parameters, so values never become SQL text. The MySQL C API has no out-of-band text-protocol parameters, so its driver escapes each value through mysql_real_escape_string before quoting it with bindQuotedValue. Use bindValue only for trusted numeric literals.

    Can I use it commercially?

    Evaluation, testing, education and non-commercial development are free. Production or other commercial use requires a paid annual Commercial Enterprise License Agreement. Email contact@ensemblu.com.

    Sovereign by default

    Stop renting your architecture from frameworks.

    Pull Axiom 3 from Maven Central today, read every line it runs, and decide for yourself.

    Copied