Releases: spiceai/spice-java
Spice Java SDK v0.6.0
Highlights
This release focuses on transport resilience and dependency upgrades. A new reset() method provides manual recovery from stuck transport connections, gRPC keep-alive detects dead connections early, and DNS re-resolution enables automatic recovery from load-balancer IP rotation.
What's New
🔄 Connection Reset
The SDK now supports a reset() method for manual transport recovery. When the underlying gRPC connection becomes permanently stuck (e.g. TLS handshake to a wrong backend, persistent UNAVAILABLE after retries), reset() discards the bad connection and immediately establishes a fresh one:
SpiceClient client = SpiceClient.builder()
.withApiKey(API_KEY)
.withSpiceCloud()
.build();
try {
try (FlightStream stream = client.query(sql)) {
// process results...
}
} catch (ExecutionException e) {
if (isTransportFailure(e.getCause())) {
client.reset(); // discard bad transport, reconnect immediately
try (FlightStream stream = client.query(sql)) {
// process results with fresh connection...
}
} else {
throw e;
}
}Key behaviors:
- Thread-safe (
synchronized) — concurrent reset calls are serialized - Idempotent — safe to call multiple times
- Throws
IllegalStateExceptionif client is already closed - Resets both Flight and ADBC connections
🏥 gRPC Keep-Alive
HTTP/2 keep-alive pings are now enabled by default to detect dead connections quickly:
- Keep-alive interval: 30 seconds
- Keep-alive timeout: 10 seconds
- Keep-alive without calls: enabled (pings even when idle)
🌐 DNS Re-Resolution
The SDK now uses dns:/// target resolution for gRPC channels, enabling periodic hostname re-resolution. This allows clients to automatically recover from load-balancer IP rotation (e.g. AWS NLB) without manual intervention.
DNS cache TTL: For more aggressive DNS refresh (recommended for cloud-deployed clients), set the JVM property:
-Dnetworkaddress.cache.ttl=30🛡️ Lazy Transport Recovery
A new ensureFlightClient() safety net automatically rebuilds the Flight client if the internal reference is null at query time, adding an extra layer of resilience.
⬆️ Updated Dependencies
| Dependency | Previous | Current |
|---|---|---|
| Apache Arrow Flight SQL | 18.3.0 | 19.0.0 |
| Apache Arrow ADBC Driver Flight SQL | 0.21.0 | 0.22.0 |
| Apache Arrow ADBC Core | 0.21.0 | 0.22.0 |
| Gson | 2.13.1 | 2.13.2 |
| Netty | 4.1.130.Final | 4.2.12.Final |
🔧 Updated Build Plugins
| Plugin | Previous | Current |
|---|---|---|
| maven-surefire-plugin | 3.5.4 | 3.5.5 |
| maven-source-plugin | 3.3.1 | 3.4.0 |
| central-publishing-maven-plugin | 0.9.0 | 0.10.0 |
| spotbugs-maven-plugin | 4.9.3.0 | 4.9.8.2 |
| dependency-check-maven | 12.1.1 | 12.2.0 |
| jacoco-maven-plugin | 0.8.13 | 0.8.14 |
| maven-enforcer-plugin | 3.5.0 | 3.6.2 |
Spice Java SDK v0.5.0
Highlights
This release introduces Parameterized Queries using ADBC (Arrow Database Connectivity), providing a safer and more efficient way to execute queries with dynamic parameters.
What's New
🎯 Parameterized Queries
The SDK now supports parameterized queries through the new queryWithParams() method. This is the recommended approach for queries with user input to prevent SQL injection attacks.
// With automatic type inference
ArrowReader reader = client.queryWithParams(
"SELECT * FROM taxi_trips WHERE trip_distance > $1 LIMIT 10",
5.0); // Double is inferred as Float64
// With multiple parameters
ArrowReader reader = client.queryWithParams(
"SELECT * FROM taxi_trips WHERE trip_distance > $1 AND fare_amount > $2 LIMIT 10",
5.0, 20.0);🔧 Explicit Type Control with Param Class
For precise control over Arrow types, use the new Param class with typed factory methods:
import ai.spice.Param;
ArrowReader reader = client.queryWithParams(
"SELECT * FROM orders WHERE order_id = $1 AND amount >= $2",
Param.int64(12345),
Param.decimal128(new BigDecimal("99.99"), 10, 2));Available typed parameter constructors:
- Integers:
int8,int16,int32,int64,uint8,uint16,uint32,uint64 - Floating point:
float16,float32,float64 - Strings:
string,largeString - Binary:
binary,largeBinary,fixedSizeBinary - Boolean:
bool - Date/Time:
date32,date64,time32,time64,timestamp,duration - Decimals:
decimal128,decimal256 - Null:
nullValue
📦 New Dependencies
- Added Apache Arrow ADBC FlightSQL driver (
adbc-driver-flight-sql:0.21.0) - Added Apache Arrow ADBC Core (
adbc-core:0.21.0) - Added Gson (
gson:2.13.1) - Added SLF4J API (
slf4j-api:2.0.17) for structured logging
⬆️ Updated Dependencies
- Apache Arrow Flight SQL: 17.0.0 → 18.3.0
- Netty: 4.1.108.Final → 4.1.130.Final
- SLF4J: 2.0.16 → 2.0.17 (moved to
slf4j-api,slf4j-simplenow test-scoped)
🔧 Updated Build Plugins
- maven-surefire-plugin: 3.3.0 → 3.5.4
- maven-source-plugin: 3.3.0 → 3.3.1
- maven-javadoc-plugin: 3.6.3 → 3.12.0
- maven-gpg-plugin: 3.2.1 → 3.2.8
- central-publishing-maven-plugin: 0.5.0 → 0.9.0
📝 Logging Support
The SDK now includes structured logging via SLF4J. Users can plug in their preferred logging implementation (Logback, Log4j2, etc.). Log messages are emitted at:
- DEBUG: Client initialization, query execution, ADBC connection lifecycle
- WARN: Recoverable errors during resource cleanup
- ERROR: Query failures, connection errors
New Files
Param.java- Parameter class with typed factory methodsParameterizedQueryTest.java- Test suite for parameterized queriesExampleParameterizedQueries.java- Example usage of parameterized queriesExampleIteratingResults.java- Comprehensive example showing how to iterate through query results
Automatic Type Inference
The following Java types are automatically inferred when passed to queryWithParams():
| Java Type | Arrow Type |
|---|---|
byte |
Int8 |
short |
Int16 |
int |
Int32 |
long |
Int64 |
float |
Float32 |
double |
Float64 |
String |
Utf8 |
boolean |
Bool |
byte[] |
Binary |
LocalDate |
Date32 |
LocalTime |
Time64 (microseconds) |
LocalDateTime |
Timestamp (microseconds, UTC) |
Duration |
Duration (microseconds) |
BigDecimal |
Decimal128/256 |
null |
Null |
🔒 Security Benefits
Parameterized queries provide protection against SQL injection attacks:
// ❌ Vulnerable to SQL injection
String userId = getUserInput(); // Could be: "1 OR 1=1"
String sql = "SELECT * FROM users WHERE id = " + userId;
FlightStream stream = client.query(sql);
// ✅ Safe from SQL injection
ArrowReader reader = client.queryWithParams(
"SELECT * FROM users WHERE id = $1",
userId);Breaking Changes
None. This release is fully backward compatible with v0.4.0.
Upgrade Guide
Simply update your dependency version from 0.4.0 to 0.5.0:
Maven:
<dependency>
<groupId>ai.spice</groupId>
<artifactId>spiceai</artifactId>
<version>0.5.0</version>
</dependency>Gradle:
implementation 'ai.spice:spiceai:0.5.0'Contributors
Thanks to everyone who contributed to this release!
What's Changed
- feat: Add x-spice-user-agent header by @peasee in #25
- docs: Add endgame release process by @peasee in #28
- feat: Add support for refresh options by @peasee in #27
- Adding custom User-Agent to Java SDK by @eadgbear in #29
- Prepend user-supplied user-agent by @phillipleblanc in #30
- Fix integration tests: Use quickstart dataset for Cloud by @sgrebnov in #33
- Add configurable Arrow memory limit -
withArrowMemoryLimitMBby @kczimm in #32 - Set version to 0.4.0 in documentation by @sgrebnov in #34
- Update end_game.md with Maven Central steps by @sgrebnov in #35
- feat: Add Parameterized Queries & Logging by @lukekim in #37
New Contributors
- @peasee made their first contribution in #25
- @eadgbear made their first contribution in #29
- @phillipleblanc made their first contribution in #30
- @kczimm made their first contribution in #32
- @lukekim made their first contribution in #37
Full Changelog: v0.3.0...v0.5.0
v0.4.0
What's Changed
- Add configurable Arrow memory limit -
withArrowMemoryLimitMBby @kczimm in #32 - Fix integration tests: Use quickstart dataset for Cloud by @sgrebnov in #33
- Fix accelerated dataset refresh by @sgrebnov in 28cdd2f
- Update version to 0.4.0 by @sgrebnov in 2b56127
Memory Configuration
The SpiceClient uses an Arrow RootAllocator to manage off-heap memory. By default, it utilizes all available memory. Starting with the 0.4.0 release, you can configure a memory limit:
SpiceClient client = SpiceClient.builder()
.withArrowMemoryLimitMB(1024) // 1GB limit
.build();New Contributors
Full Changelog: v0.3.0...v0.4.0
v0.3.0
v0.2.0
Spice Java SDK v0.1.0
What's Changed
- Java SDK core functionality and tests by @sgrebnov in #1
- Add publishing to Maven Central by @sgrebnov in #2
- Implement connection retry mechanism by @sgrebnov in #5
- Implement AutoCloseable interface for SpiceClient by @sgrebnov in #7
- Fix Maven link for SDK artifacts by @sgrebnov in #8
- Update Readme to match the latest code version by @sgrebnov in #9
- Update README.md - small edits and improvements by @digadeesh in #10
- Fix Maven publishing: add required step to load signing key by @sgrebnov in #11
- Set version to 0.1.0 by @sgrebnov in #12
New Contributors
- @sgrebnov made their first contribution in #1
- @digadeesh made their first contribution in #10
Full Changelog: https://github.com/spiceai/spice-java/commits/v0.1.0