- Built on Rust SDK 2.0.1: The JNI layer (
rust/jni/) now depends ondatabricks-zerobus-ingest-sdk = "2.0.1"(was 2.0.0). The Java-facing API surface (ZerobusSdk,ZerobusProtoStream,ZerobusJsonStream,ZerobusArrowStream,StreamConfigurationOptions,ArrowStreamConfigurationOptions) is unchanged. - Arrow Flight promoted to Beta:
ZerobusArrowStream/ArrowStreamConfigurationOptionsand the surrounding documentation (README, examples) are no longer labelled experimental. The API is stabilising but may still change before reaching GA. (Mirrors the Rust SDK 2.0.1 promotion.) ArrowStreamConfigurationOptions: AddedstreamPausedMaxWaitTimeMsfor the maximum time (milliseconds) to wait in the paused state during graceful close (-1= full server duration,0= immediate recovery).- Java SDK identifier on the wire: The SDK now reports itself as
zerobus-sdk-java/<version>on the HTTPuser-agentheader (previously it inherited the Rust SDK identifierzerobus-sdk-rs/<rust-version>). Server-side telemetry can now distinguish Java clients from Rust clients.
-
StreamConfigurationOptions.maxInflightRecordsdefault raised from50_000to1_000_000to match the Rust SDK 2.0.1 default. The Java wrapper previously hard-coded 50k while the Rust SDK quietly raised its default to 1M, so Java clients ran with a 20× lower in-flight ceiling than Rust clients. Callers who relied on the old cap can pin it back explicitly:StreamConfigurationOptions.builder() .setMaxInflightRecords(50_000) .build();
- Updated
ArrowIngestionExample.javato demonstrate all three IPC compression codecs end-to-end. Opens three streams in sequence (NONE,LZ4_FRAME,ZSTD), ingests 10 batches per stream, thenwaitForOffset+flush+close. - Updated
README.md,examples/README.md,examples/arrow/README.md, and Javadoc onZerobusArrowStream/ArrowStreamConfigurationOptions/ZerobusSdk.createArrowStreamto reflect the Beta promotion. - Documented the JDK 9+
--add-opens=java.base/java.nio=...JVM flags required byarrow-memory-netty17.x when usingZerobusArrowStream, in both the main README and the Arrow examples README.
maven-surefire-pluginnow passes the required--add-opensflags so Arrow integration tests run cleanly on JDK 9+ without per-developer setup.- Bumped
zerobus-jnicrate version from1.1.1to1.2.0(used by the Java SDK identifier embedded at compile time viaCARGO_PKG_VERSION).
- Fixed
isClosed()returningfalseafter the stream internally closed due to non-retryable errors (e.g. server rejection, auth failure). The JNI layer now checks both the wrapper state and the Rust stream's internal closed flag. Affects both proto/JSON streams and Arrow streams.
- License: Migrated from the Databricks License to the Apache License 2.0
- Arrow Flight Support (Experimental): Added support for ingesting Apache Arrow
VectorSchemaRootbatches via Arrow Flight protocol- Note: Arrow Flight is not yet supported by default from the Zerobus server side.
- New
ZerobusArrowStreamclass withingestBatch(),waitForOffset(),flush(),close(),getUnackedBatches()methods - New
ArrowStreamConfigurationOptionsfor configuring Arrow streams (max inflight batches, recovery, timeouts, IPC compression) - Configurable IPC compression via
ArrowStreamConfigurationOptions.setIpcCompression()(supportsLZ4_FRAMEandZSTD) - New
createArrowStream()andrecreateArrowStream()methods onZerobusSdk - Accepts
VectorSchemaRootdirectly viaingestBatch()(IPC serialization handled internally) - Arrow is opt-in: add
arrow-vectorandarrow-memory-nettyas dependencies (provided scope,>= 15.0.0)
- Classloader Isolation Compatibility: Fixed
NoClassDefFoundErrorwhen using the SDK inside Spring Boot. JNI class references are now cached asGlobalRefs duringJNI_OnLoad, so native daemon threads no longer rely onFindClassthrough the system classloader. - Fixed proto generation tool to skip reserved field numbers 19000-19999 for tables with more than 19000 columns
- Added
arrow-vector17.0.0 as provided dependency for Arrow Flight support - Added
arrow-memory-netty17.0.0 as test dependency for integration tests - Uses existing JNI Arrow Flight bindings from Rust SDK (
nativeCreateArrowStream,nativeIngestBatch, etc.)
- Added
createArrowStream(String tableName, Schema schema, String clientId, String clientSecret)toZerobusSdk - Added
createArrowStream(String tableName, Schema schema, String clientId, String clientSecret, ArrowStreamConfigurationOptions options)toZerobusSdk - Added
recreateArrowStream(ZerobusArrowStream closedStream)toZerobusSdk - Added
ZerobusArrowStreamclass with methods:ingestBatch(),waitForOffset(),flush(),close(),getUnackedBatches(),isClosed(),getTableName(),getOptions() - Added
ArrowStreamConfigurationOptionsclass with fields:maxInflightBatches,recovery,recoveryTimeoutMs,recoveryBackoffMs,recoveryRetries,serverLackOfAckTimeoutMs,flushTimeoutMs,connectionTimeoutMs,ipcCompression - Added
IPCCompressionTypeenum with values:NONE,LZ4_FRAME,ZSTD - Added optional dependency:
org.apache.arrow:arrow-vector >= 15.0.0(provided scope)
- Fixed TLS certificate validation failure when behind corporate VPN/proxy with MITM certificates (e.g., GlobalProtect). The underlying Rust native library now loads CA certificates from the OS native trust store (respecting
SSL_CERT_FILEand system certificate stores) while keeping bundled Mozilla roots as a fallback.
GA release of the Databricks Zerobus Ingest SDK for Java.
- Added HTTP proxy support via standard environment variables (
grpc_proxy,https_proxy,http_proxy), following gRPC core conventions. Proxied connections use HTTP CONNECT tunneling with end-to-end TLS. Supportsno_grpc_proxy/no_proxyfor bypass rules.
- Updated native Rust backend to v0.6.0
- Schemeless server endpoints now automatically get
https://prepended - All documentation and examples updated to explicitly use
https://prefixed endpoints - Added Linux aarch64 (ARM64) native library support
- The SDK now uses JNI (Java Native Interface) to call the Zerobus Rust SDK instead of pure Java gRPC calls
- Native library is automatically loaded from the classpath or system library path
- Token management and background processing handled by native code
ZerobusProtoStream - Protocol Buffer ingestion with method-level generics:
ingestRecordOffset(T record)- Auto-encoded: SDK encodes Message to bytesingestRecordOffset(byte[] bytes)- Pre-encoded: User provides encoded bytesingestRecordsOffset(List<T> records)- Batch auto-encoded ingestioningestRecordsOffset(List<byte[]> bytes)- Batch pre-encoded ingestiongetUnackedRecords()- ReturnsList<byte[]>of unacked recordsgetUnackedRecords(Parser<T>)- Returns parsedList<T>of unacked recordsgetUnackedBatches()- ReturnsList<EncodedBatch>preserving batch grouping
ZerobusJsonStream - JSON ingestion without Protocol Buffer dependency:
ingestRecordOffset(String json)- Pre-serialized: User provides JSON stringingestRecordOffset(T obj, JsonSerializer<T>)- Auto-serialized: SDK serializes objectingestRecordsOffset(List<String> jsons)- Batch pre-serialized ingestioningestRecordsOffset(List<T> objs, JsonSerializer<T>)- Batch auto-serialized ingestiongetUnackedRecords()- ReturnsList<String>of unacked JSON recordsgetUnackedRecords(JsonDeserializer<T>)- Returns parsedList<T>of unacked recordsgetUnackedBatches()- ReturnsList<EncodedBatch>preserving batch grouping
ZerobusSdk.createProtoStream(tableName, descriptorProto, clientId, clientSecret)- Create proto streamZerobusSdk.createProtoStream(tableName, descriptorProto, clientId, clientSecret, options)- With optionsZerobusSdk.createJsonStream(tableName, clientId, clientSecret)- Create JSON streamZerobusSdk.createJsonStream(tableName, clientId, clientSecret, options)- With optionsZerobusSdk.recreateStream(ZerobusProtoStream)- Recreate proto stream with unacked record re-ingestionZerobusSdk.recreateStream(ZerobusJsonStream)- Recreate JSON stream with unacked record re-ingestionZerobusSdk.recreateStream(ZerobusStream)- Recreate legacy stream (deprecated)
BaseZerobusStream- Abstract base class with native JNI methodsJsonSerializer<T>- Functional interface for object-to-JSON serializationJsonDeserializer<T>- Functional interface for JSON-to-object deserializationEncodedBatch- Represents a batch of encoded records for recoveryAckCallback- Callback interface withonAck(long)andonError(long, String)
ZerobusStream - Use ZerobusProtoStream instead:
ingestRecord(T record)- ReturnsCompletableFuture<Void>, useingestRecordOffset()insteadgetStreamId()- No longer exposed by native backend, returns empty stringgetState()- ReturnsOPENEDorCLOSEDonlygetUnackedRecords()- Breaking: Returns empty iterator (records stored in native, type erasure prevents deserialization). UseZerobusProtoStream.getUnackedRecords(Parser<T>)for typed access, or userecreateStream()which handles re-ingestion automatically using cached raw bytes.
StreamConfigurationOptions:
setAckCallback(Consumer<IngestRecordResponse>)- No longer invoked by native backend. UsesetAckCallback(AckCallback)instead
TokenFactory- Token management now handled by native Rust SDKBackgroundTask- Background processing now handled by native Rust SDKZerobusSdkStubUtils- gRPC stub utilities no longer needed with native backend
- Linux x86_64: Supported
- Windows x86_64: Supported
- macOS x86_64: Supported
- macOS aarch64 (Apple Silicon): Supported
Initial release of the Databricks Zerobus Ingest SDK for Java.
- Added
ZerobusSdkclass for creating ingestion streams - Added
ZerobusStreamclass for managing stateful gRPC streams - Added
RecordAcknowledgmentfor blocking until record acknowledgment - Added
TablePropertiesfor configuring table schema and name - Added
StreamConfigurationOptionsfor stream behavior configuration - Added
ZerobusExceptionandNonRetriableExceptionfor error handling - Added
StreamStateenum for tracking stream lifecycle - Added utility methods in
ZerobusSdkStubUtilsfor gRPC stub management - Support for Java 8 and higher