CratonVM
The Java Runtime for AI Inference and Big Data at Scale
Version 0.3.0 · Java SE 8–25 · 2M+ lines of Rust · 20K+ automated tests · by Craton Software Company
The bytecode you already have is the input.
You compile with javac and you run with a flag. The analyzer reads your bytecode, decides which methods it can lower to PTX while guaranteeing an identical result, and moves those. Everything else runs on the JIT.
Not a diagram of the architecture — a live model of it. Three mechanisms at once, with the real objects moving through them.
Along the top, the analyzer branches every method: what it can prove equivalent goes to PTX and the device, everything else to the JIT. Bottom left, one method climbs the tiers — and the interpreter keeps running while the background worker compiles it, because codegen is off-thread by default. Bottom right, allocations rain into the heap and ZGC marks it concurrently, without stopping the program above.
Java owns your data layer and almost none of your compute.
Rewrite the kernel
In CUDA C, or in a framework that asks you to restructure the work around its own graph API and annotate every parallel loop. Either way there is now a second language in code review, a second build, and a native artifact per platform in your release pipeline.
Move the workload out
To a Python service, where your data leaves the JVM on every call and you have acquired a second deployment, a second on-call rotation, a second auth surface, and a network hop in the middle of a hot loop.
Or change the runtime
CratonVM removes the boundary instead of moving it. Your bytecode is the input; the GPU is a target the runtime already knows how to reach.
cargo build --release -p cratonvm-cli --features gpu-driver
./target/release/cratonvm --gpu -c . MyPipeline
# and to see every verdict and the reason behind it:
./target/release/cratonvm --gpu --print-gpu-decisions -c . MyPipelineSame hardware. Only the software varies.
TornadoVM is the best-known Java GPU framework and the fair comparison. It asks you to annotate kernels, restructure them around a TaskGraph API, and adopt new array types before a single line moves. CratonVM asks for none of that.
| Compute kernel (16.7M+ elements) | CPU (HotSpot C2) | TornadoVM GPU | CratonVM GPU | vs HotSpot | vs TornadoVM |
|---|---|---|---|---|---|
| Integer division chain | 2,179 ms | 27 ms | 7 ms | 311x faster | 3.9x faster |
| Double-precision division chain | 1,784 ms | 135 ms | 82 ms | 21.8x faster | 1.6x faster |
| 128 multiply-adds/element | 1,298 ms | 26 ms | 7 ms | 185x faster | 3.7x faster |
| Dot-product reduction (int·int → long) | 1,168 ms | unimplemented | 2 ms | 584x faster | — |
| Ray tracer kernel (33.2M pixels) | 837 ms | 24.3 ms | 12.3 ms | 68x faster | 2.0x faster |
Measured 2026-09-07 on a verified-quiet host: RTX 2060, TornadoVM 4.0.1 (PTX backend), N = 2²⁴, best of 5, warm, full host→device→host round-trip. Every arm of a row ran in the same session, including the CPU baselines, so the columns are comparable to each other — and those baselines reproduced the previous run's almost exactly, which is the check that the setup is sound. The ray-tracer row is carried over from an earlier measurement and was not re-run.
The unimplemented row is not a gap in our table. TornadoSnippetReflectionProvider.forBoxed is an unconditional stub in both the 4.0.1 jar and current master, so a @Reduce kernel needing an int→long widening before accumulating into a differently-typed reduce array cannot run there. We isolated it with three minimal repros on the same GPU rather than inferring it from a stack trace.
Two tilings, chosen by the shape of your output.
CratonVM ships GEMM — the computation behind every neural-network layer, every attention block, every inference pass — as a built-in GPU kernel in both fp32 and fp16. Not one kernel pretending to suit every shape:
128×128 tile
Better arithmetic intensity — 64 FMAs per 16 shared loads — but it covers a 256×256 problem in four blocks and leaves most of a 30-SM device idle. 58% faster at N=1024.
64×64 tile
Lower intensity per block, four times as many of them, and enough to fill the machine at modest sizes. 67% faster at N=256.
The winner reverses
Small attention heads and large projection layers want opposite answers. The host picks by output size, so you get the right one without asking for it.
For Java that wants to call this directly rather than rely on automatic offload, gpu4j is the typed API onto this runtime: GpuBlas, device-resident GpuArray, fp16 Half, streams and CUDA graph capture — one Maven dependency, no CUDA toolchain, no JNI.
Throughput, uptime, and heaps that don't stall under load.
A collector for large heaps
ZGC by default: concurrent marking, compaction, colored pointers and a load barrier, with an opt-in generational mode. Sized for the memory profile real data services carry — not a decades-old collector stretched to cover a new decade.
Your stack already runs
Spring and Spring Boot, Tomcat, and Hibernate boot, run and pass their real test suites on CratonVM today, backed by a full embedded H2 SQL database. Netty, Quarkus and Hibernate Reactive are next.
One self-contained binary
No JDK to install, no rt.jar, no bloated base image. Download it and run it — in a container, at the edge, in a pipeline, wherever your data actually lives.
Memory-safe by construction
Interpreter, JIT and collector in safe Rust wherever the problem allows, closing off entire categories of memory-corruption bug that have shadowed native runtimes for decades. 400,000+ lines across 22 crates.
A real optimizing JIT
Not a fast interpreter: tiered compilation, on-stack replacement, bounds-check elimination, AVX2 vectorization — hot loops compiled straight to native x86-64.
Modern Java, fully covered
Java 8 through 25 — lambdas and streams, records and sealed classes, pattern matching, virtual threads, scoped values. 19,000+ tests checked against real HotSpot behaviour.
Better to find these out here than in week three.
The automatic path is narrow
It is not a promise that arbitrary Java runs on the accelerator. It is a promise that what does run returns the same answer, and that you can ask why anything was declined.
NVIDIA only, for now
GPU offload needs a CratonVM built with --features gpu-driver and an NVIDIA device. The CPU runtime has no such requirement.
Pre-1.0 and fast-moving
Java SE 8–25 is covered and 19,000+ tests enforce it, but this is a young runtime. Bring us your workload and we will tell you honestly whether it is ready for you.
Bring us a workload.
cargo build --release -p cratonvm-cli
./target/release/cratonvm -cp . HelloWorldA batch that runs too long, a model you cannot serve economically, a pipeline stage that dominates your cluster bill — we will benchmark it against what you run today, and tell you if the answer is no.