Every eligible method body is exported to an intermediate representation, translated to
Rust, and compiled, together with every other method that translated successfully, into
one shared native library for the whole JAR. Each method is flipped to a bare
native declaration and bound through JNI's RegisterNatives.
A bootstrap native method, resolved by the JVM's default symbol-mangling convention
and not through RegisterNatives itself, receives the caller's
Class object as an argument at first use. Registration therefore always
targets the right class, regardless of which class loader defined it or
how many other classes share the same native library.
Supported today: core arithmetic and control flow (branches, loops), object and array
access, casting and instanceof, exceptions (throw, and an
exception not caught inside a translated method propagates out of it with its original
type), whole-method synchronized, lambdas
and method references created via LambdaMetafactory, non-virtual calls
(super.foo(), private-method calls), and null-safety matching the JVM's
semantics: a null dereference throws a catchable NullPointerException
instead of causing undefined behaviour in the compiled native code.
Not yet supported, and excluded, not mistranslated: multi-dimensional array
literals, block-level synchronized(obj), object reference-equality branches,
nested try/catch blocks, and a small number of rarer shapes.
Full list: Known limitations.
Nativization runs last among the code-transforming passes (stage 4–5 of the six-stage pipeline), after class renaming, string encryption, member renaming, and control-flow flattening have already run. This means a nativized method's JNI signature and generated Rust code reflect final, post-rename identifiers, and any string literal it used has already been replaced with an encrypted payload and a runtime decrypt call, so the compiled native code never embeds plaintext.
Removes the method's Code attribute entirely, so there is no bytecode body
left for a decompiler to reconstruct. The trade-off: RegisterNatives
is a name-based JNI API, so the method's exact name and JVM descriptor remain visible as
plaintext strings inside the compiled native library, whatever that
name currently is (a renamed method reveals its renamed name, not the original, which is the intended outcome). See Security model.