JVM SDKs (Java & Kotlin)
Relevant source files
The following files were used as context for generating this wiki page:
Crucible generates SDKs for the Java Virtual Machine (JVM) targeting both Java 17 and Kotlin Multiplatform. These SDKs provide synchronous and asynchronous HTTP clients, strongly typed models, and support for automated pagination and retries based on a shared Intermediate Representation (IR).
Sources: crates/crucible-codegen-java/src/lib.rs:1, crates/crucible-codegen-kotlin/src/lib.rs:1
Shared Architecture
The JVM SDK generators share common logic for handling recursive collections, type mapping, and naming conventions. Both generators produce a service client class, a configuration object, and a set of model classes representing the API's data structures.
Type Mapping and Namespaces
Crucible maps Smithy-based simple kinds to native JVM types. It uses java.time.Instant for timestamps and com.google.gson.JsonElement (Java) or kotlinx.serialization.json.JsonElement (Kotlin) for document types.
| Smithy Kind | Java Type | Kotlin Type |
|---|---|---|
| String | java.lang.String | kotlin.String |
| Boolean | java.lang.Boolean | kotlin.Boolean |
| Long | java.lang.Long | kotlin.Long |
| Timestamp | java.time.Instant | kotlin.time.Instant |
| BigInteger | java.math.BigInteger | com.ionspin.kotlin.bignum.integer.BigInteger |
| Document | com.google.gson.JsonElement | kotlinx.serialization.json.JsonElement |
Sources: crates/crucible-codegen-java/src/lib.rs:163-181, crates/crucible-codegen-kotlin/src/lib.rs:136-154
Recursive Collections
JVM type aliases for recursive lists or maps require a nominal class to break the cycle. Crucible identifies these cycles and generates final classes that extend standard collection types (e.g., ArrayList or LinkedHashMap) to ensure the JVM can represent the recursive structure.
Sources: crates/crucible-codegen-java/src/lib.rs:374-411, crates/crucible-codegen-kotlin/src/lib.rs:589-608
Java SDK Implementation
The Java generator produces Java 17 records for enums and final classes for structures and unions. It uses a builder pattern for object construction and supports both synchronous and asynchronous execution through java.util.concurrent.CompletableFuture.
Client Structure
The Java client uses a ClientRuntime to handle the underlying HTTP communication and JSON serialization.
Model Generation
- Structures: Generated as final classes with public fields. They include a nested
Builderclass. - Unions: Implemented as final classes where exactly one variant is set. Unknown variants are preserved in an
unknownVariantfield. - Enums: Represented as records to allow preservation of unknown wire values while providing static constants for known values.
Sources: crates/crucible-codegen-java/src/lib.rs:444-480, crates/crucible-codegen-java/src/lib.rs:482-550
Kotlin SDK Implementation
The Kotlin generator targets Kotlin Multiplatform and utilizes coroutines for non-blocking I/O. It produces suspend functions for operations and cold Flow objects for paginated results.
Coroutine-Based Communication
Every API operation in the Kotlin SDK is a suspend function. The client is AutoCloseable and must be closed to release internal resources.
Paginated Snippets
Kotlin operations marked as @paginated receive an additional <Operation>Pages method. This method returns a Flow that lazily fetches pages as they are consumed.
client.listItemsPages(input).collect { page ->
println(page.items)
}
Sources: crates/crucible-codegen-kotlin/src/snippet.rs:324-345, crates/crucible-codegen-kotlin/src/lib.rs:517-535
Comparison of SDK Features
| Feature | Java 17 SDK | Kotlin Multiplatform SDK |
|---|---|---|
| Async Primitive | CompletableFuture<T> | suspend functions |
| Pagination | Iterator<T> or Flow.Publisher<T> | Flow<T> |
| Models | Records (Enums) / Classes (Structs) | Classes with DSL builders |
| Default JSON | GSON | kotlinx.serialization |
| Retries | Built into ClientRuntime | Built into ClientRuntime |
Sources: crates/crucible-codegen-java/src/lib.rs:24-35, crates/crucible-codegen-kotlin/src/lib.rs:114-125, crates/crucible-codegen-kotlin/src/snippet.rs:360-385
Error Handling
Both SDKs handle modeled errors by generating specific exception classes that extend a base ServiceException. Transport-level failures (e.g., connection timeouts) throw a NetworkError.
- Service Errors: Mapped from the IR's error shapes. Includes
status,requestId, andheaders. - Throttling: Modeled errors can be marked as retryable/throttling in the IR, which the runtime respects.
- Redaction: Sensitive members are redacted in the
toString()implementation of model classes using aModelFormatutility.
Sources: crates/crucible-codegen-java/src/lib.rs:553-568, crates/crucible-codegen-kotlin/src/lib.rs:385-395, crates/crucible-codegen-csharp/src/lib.rs:480-495
Summary
Crucible's JVM SDKs provide a robust, type-safe interface for interacting with modeled services. The Java SDK prioritizes compatibility and standard Java concurrency patterns, while the Kotlin SDK leverages modern language features like coroutines and flows for a more ergonomic developer experience in multiplatform environments. Both utilize a shared runtime logic for consistent behavior regarding retries, authentication, and serialization.