The short answer
No — there is no condition under which the COBOL standard guarantees consistent behavior when a REPLACE statement's subject overlaps with other referenced fields. The result is explicitly undefined, and the two compilers you are most likely mixing with Java (IBM Enterprise COBOL and Micro Focus Visual COBOL) implement it differently. A portable COBOL-to-Java interface must therefore be designed so that REPLACE never operates on overlapping storage, full stop.
What actually differs between compilers
REPLACE works at the byte level on the contiguous storage of its subject item. When subordinate fields overlap that storage, the order of operations matters:
- IBM Enterprise COBOL (z/OS) processes the replacement left-to-right, in place. Bytes written by an earlier replacement are visible to later match attempts, so overlapping fields observe the mutated content immediately.
- Micro Focus Visual COBOL has historically staged the operation through a temporary buffer, so all matches are determined from the original content before anything is written back.
Neither behavior is a bug — the standard permits both. But when the record is handed to Java (via a JCA record adapter, JNI, or Micro Focus JVM COBOL), the Java consumer simply sees whatever byte pattern the COBOL runtime produced. The same source program yields two different data contracts depending on which compiler built it. Note also that on IBM, character width (USAGE DISPLAY vs. NATIONAL) can further change the outcome, so even a single-vendor shop is not immune.
One caveat worth flagging: the exact internal mechanics above are based on documented and observed behavior, but neither vendor commits to them as a stable interface, and Micro Focus JVM COBOL's implementation could shift across releases. Treat any observed overlap behavior as non-portable by definition.
Designing a portable interface
The reliable fix is to remove overlap from the equation rather than to standardize its semantics:
- Constrain the copybook. Lay out records so no two business fields share storage — use FILLER separation and avoid REDEFINES on fields that REPLACE will touch. If REPLACE only ever targets a discrete elementary item, overlap cannot occur.
- Prefer INSPECT on elementary items. An INSPECT ... REPLACING on a single non-overlapping elementary field has defined behavior and communicates intent more clearly.
- Move transformation to Java. Pass the raw record across the boundary and perform string substitution in Java after deserialization. This makes the data contract compiler-independent and unit-testable with ordinary JUnit assertions.
- Serialize to a canonical format. If the integration is new, consider emitting JSON or Protobuf from COBOL rather than sharing raw record layouts; this decouples the contract from COBOL storage semantics entirely.
Mitigations for existing deployments
If you cannot rewrite the COBOL today:
- Replace the offending REPLACE with a PERFORM loop over discrete elementary items — verbose, but deterministic everywhere.
- Add a runtime assertion after the REPLACE (compare the result against the expected value and log on divergence) so cross-platform drift is caught in test rather than in production Java consumers.
- Write a boundary test: run the record through REPLACE, deserialize on the Java side, and assert the expected non-overlapping result. Run it against every compiler/JVM combination you ship.
Be aware that static analysis tools generally will not flag REPLACE overlap — it is legal syntax — so detection requires a coding-standard review or a custom rule, not your existing analyzer.
Verifying your specific case
Compile a minimal program exercising your exact record layout under both compilers, hex-dump the record before and after, and compare. On Micro Focus JVM COBOL, javap -c on the generated class will show whether a temporary buffer is used. Confirm against the current language references for your exact compiler versions, since these details are implementation-defined and can change.