bluetape4k-dependencies 1.3.0 in Practice Part 1: Features and Cleanup

bluetape4k-dependencies is a BOM for using several bluetape4k libraries on one coherent dependency line. Moving to
1.3.0 is not only a number change. It pulls in changes from projects, exposed, aws, image, text, leader,
graph, and javers.
This post looks at four questions:
- What became usable?
- Which bugs were fixed?
- Why did those bugs happen?
- Where should application code be careful?
Included Libraries
Section titled “Included Libraries”| Library | Version | Main change |
|---|---|---|
projects | 1.11.0 | fixed Connection state restoration in JDBC transaction helpers |
exposed | 1.11.0 | cache health indicator, BigQuery dry-run, CockroachDB retry helpers |
aws | 0.4.0 | Ktor CloudWatch/Logs plugin and DynamoDB/DAX/IMDS/S3 improvements |
image | 0.3.0 | OCR examples and Okio-based large-file image I/O |
text | 0.2.1 | safer web-service examples for tokenizers and blockword APIs |
leader | 0.4.0 | backend examples, performance evidence, Kubernetes runtime conflict fix |
graph | 0.5.1 | stabilized 0.5.x patch consumption |
javers | 0.2.1 | dependency boundary cleanup for JaVers/Exposed integration |

projects 1.11.0: Return the Connection You Borrowed
Section titled “projects 1.11.0: Return the Connection You Borrowed”The most concrete fix in projects 1.11.0 is
Connection.withTransaction.
The helper must not leave the caller’s Connection in a different state after the transaction helper finishes. The fix
restored more of the original state, including autoCommit, isolation, and isReadOnly, and widened failure handling
beyond a narrow Exception path.
connection.withTransaction { // work runs with transaction settings}
// original connection state must be restored hereThe regression matters because pooled connections are borrowed objects. If one borrower leaves isReadOnly or
autoCommit wrong, the next borrower pays for it.
Useful checks include:
- a connection that already starts with
autoCommit=false - a connection that already starts with
isReadOnly=true - a failure that is not a plain
Exception - rollback succeeds but restore fails
- read-only transactions leave the original read-only state intact afterward
exposed 1.11.0: A Cache Should Look Sick When It Is Sick
Section titled “exposed 1.11.0: A Cache Should Look Sick When It Is Sick”exposed 1.11.0 added and refined several operational boundaries:
cache consistency health indicator- BigQuery query dry-run before execution
- CockroachDB transaction retry helpers
- dialect options such as Trino session settings
For a write-behind cache, the important question is not only whether get() returns quickly.
- Is the write-behind queue backing up?
- Did the flush job stop?
- What was the last flush error?
- Does health still say
UPwhen consistency checks are failing?
{ "status": "OUT_OF_SERVICE", "details": { "mode": "WRITE_BEHIND", "queueDepth": 128, "flushJobRunning": false, "lastFlushError": "RedisConnectionFailureException" }}Cache health is not a dashboard extra. It decides whether operators can see delayed consistency before users report the symptom.
aws 0.4.0: A CloudWatch Plugin Should Not Own the Application
Section titled “aws 0.4.0: A CloudWatch Plugin Should Not Own the Application”aws 0.4.0 added a
Ktor CloudWatch/Logs plugin and improved DynamoDB, optional
DAX, IMDS, S3 Access Grants, S3 Vectors, and Micrometer-facing observability paths.
The lifecycle rules are the important part:
- send nothing by default
- do not close AWS clients supplied by the user
- close only clients the plugin created
- bound shutdown flush time
- do not swallow cancellation
- do not silently change global logging settings
install(BluetapeAwsCloudWatch) { namespace = "billing-api" serviceName = "billing"}The plugin should make metric/log emission explicit without becoming the owner of the entire application lifecycle.
image 0.3.0: File Size Comes Before OCR Options
Section titled “image 0.3.0: File Size Comes Before OCR Options”image 0.3.0 added
images-ocr examples and
large-file image I/O through Okio Source/Sink
paths.
OCR examples are useful only if the input path survives real files.
// Fine for small samples. Dangerous as the default upload path.val bytes = multipartFile.bytesval text = ocr.read(bytes)The service should decide upload limits, temporary-file behavior, maximum pixels, native runtime failure handling, OCR timeouts, and empty-result behavior before spending time on OCR quality.
text 0.2.1: Tokenizer APIs Behind HTTP Need Input Policy
Section titled “text 0.2.1: Tokenizer APIs Behind HTTP Need Input Policy”text 0.2.1 strengthened runnable text-search examples, Lingua detector reuse and threshold tests, and the
tokenizer/blockword web-service safety example.
The service boundary matters:
request.text.requireLength(max = 10_000)val normalized = normalizer.normalize(request.text)val tokens = koreanTokenizer.tokenize(normalized)Tokenizers, language detectors, and blockword dictionaries are library APIs, but once they sit behind REST endpoints, input length, redaction, validation failures, and error responses become service contracts.
leader 0.4.0: Provider Choice Can Be the Hard Part
Section titled “leader 0.4.0: Provider Choice Can Be the Hard Part”leader 0.4.0 organized Redis, SQL, Kubernetes, Consul, etcd, and DynamoDB backend examples, added more performance
evidence, and fixed a
Kubernetes K3s test runtime conflict.
Choosing a provider also chooses storage and runtime dependencies.
Redis provider -> Redis latency and failover behaviorSQL/Exposed provider -> DB lock waits and transaction boundariesKubernetes Lease -> API server, Fabric8, service account permissionsDynamoDB provider -> IAM, capacity, region, conditional writesWhen a backend brings a sensitive runtime line, inspect the classpath instead of guessing.
./gradlew dependencyInsight --dependency fabric8 --configuration runtimeClasspathgraph and javers: Small Patch Lines Still Matter
Section titled “graph and javers: Small Patch Lines Still Matter”graph 0.5.1 stabilizes the 0.5.x patch line. javers 0.2.1 is mostly about dependency boundary cleanup around
JaVers and Exposed integration. These are not headline features, but they keep the combined dependency graph easier to
consume.
Closing
Section titled “Closing”After moving to dependencies 1.3.0, check the boundaries that are easy to miss:
- does a JDBC helper restore the original
Connectionstate? - can cache health show queue depth, flush liveness, and last error?
- does the CloudWatch/Logs plugin respect client and application lifecycle?
- does OCR load an entire file into memory?
- do tokenizer/blockword endpoints enforce length and redaction policy?
- did leader provider choice bring a runtime dependency that needs inspection?
- do smaller
graphandjaverspatch lines keep the dependency graph stable?
Series
Section titled “Series”If you want the first import path, start with the usage guide.
- bluetape4k-dependencies 1.3.0 in Practice Part 1: Features and Cleanup
- bluetape4k-dependencies 1.3.0 in Practice Part 2: Selecting Modules by Service Boundary
- bluetape4k-dependencies 1.3.0 in Practice Part 3: Production Signals
- bluetape4k-dependencies 1.3.0 in Practice Part 4: Input Boundaries
Resources
Section titled “Resources”- Release line and version matrix:
bluetape4k-dependenciesCHANGELOG - Representative implementations:
bluetape4k-projects,bluetape4k-exposed,bluetape4k-aws - I/O, text, and leader-election examples:
bluetape4k-image,bluetape4k-text,bluetape4k-leader
Comments
Leave a note or reaction with your GitHub account.