Expand description
IDL service → Java RPC codegen (DDS-RPC 1.0 §7.11.2 — Java PSM).
This module is the bridge between the typed RPC data model
from zerodds-rpc (ServiceDef/MethodDef/ParamDef) and the
Java source codegen. Per service we emit four classes:
<Service>.java— synchronous interface with all methods (throws RemoteException+ user exceptions).<Service>Async.java— asynchronous interface withCompletableFuture<TOut>returns (spec §7.11.2.2.4 mapsFuture<T>tojava.util.concurrent.Future<T>; we useCompletableFutureas a full implementation).<Service>Requester.java— client side: wraps aorg.zerodds.rpc.Requester<TIn,TOut>and implements<Service>+<Service>Async.<Service>Replier.java— server side: wraps aorg.zerodds.rpc.Replier<TIn,TOut>and dispatches incoming requests to a<Service>Servicehandler.<Service>Service.java— server-side handler interface: the service implementor implements this interface.
§Out parameters
Java has no out/inout concept. We map out/inout via the
holder pattern (spec §7.11.2.3 / IDL-to-Java 1.3 §1.5):
public final class IntHolder {
public int value;
public IntHolder() {}
public IntHolder(int v) { this.value = v; }
}Holders are not emitted per service — we reference the
generic holders from org.zerodds.rpc.Holder<T> (see
runtime/rpc/Holder.java). Rationale: less boilerplate than
per-type holders, fully compatible with the spec pattern (the
caller writes to holder.value before the call, the reply decoder
overwrites it on return). The alternative Object[] wrapper would be
type-unsafe and is therefore ruled out.
§Exception mapping (spec §7.11.2.1)
- IDL
exception E { ... }→ we delegate to the existingemit_exception_filepath (E extends RuntimeException); the RPC codegen only adds thethrows E1, E2clause on the method. org.zerodds.rpc.RemoteExceptionis a RuntimeException subclass that every RPC method may throw implicitly — we therefore do not place it explicitly in thethrowslists, because RuntimeException is not checked in Java.
§Marshalling convention
The requester/replier marshal a type-erased tuple
through the runtime Requester<Object,Object> / Replier<Object,Object>:
the request payload is an Object[] of the IN + INOUT values (declaration
order); the reply payload is an Object[] { returnValue-or-null, INOUT+OUT values… }. The requester writes the INOUT/OUT holders back from the reply
and casts the return value; the replier decodes the request tuple, builds
holders, calls the handler, and packs the reply. The generated code is
verified to compile against the real runtime by
tests/compile_check.rs (real javac, no stubs).
§What this stage does NOT do
- No
mvnpackaging — callers drop theruntime/sources (or a jar) alongside the generated code (seeruntime/README.md). - No reflection TypeRep (a stretch in idl4-java §8).
Functions§
- emit_
replier_ class - Emits the server-side replier class (
<Service>Replier.java). - emit_
requester_ class - Emits the client-side requester class (
<Service>Requester.java). - emit_
service_ files - Convenience wrapper: emits all 5 Java files for one service.
- emit_
service_ handler_ interface - Emits the server-side handler interface (
<Service>Service.java). - emit_
service_ interface - Emits the synchronous service interface (
<Service>.java). - emit_
service_ interface_ async - Emits the asynchronous service interface (
<Service>Async.java).