COMP-3 packed decimals
The ProblemCOMP-3 is signed packed binary-coded decimal
often used to represent "money" values. Java and C# doubles are IEEE 754 floating point.
Mapping decimal "money" values to doubles loses precision and produces incorrect results for
any kind of financial code, often not discovered until months after cutover.
How DMS handles itEvery COMP-3 field maps to a target language native type
(Java: "BigDecimal" or C# "decimal"), or ScaleLongs (customer choice) that preserve scale,
precision, and rounding exactly as COBOL semantics require. Our ScaleLongs implementation
is an order of magnitude faster than the native types, and even exceed mainframe decimal math speeds.
REDEFINES and memory aliasing
The ProblemCOBOL data semantics are
technically based on a "byte memory image" of data. REDEFINES lets the
same byte memory be aliased/interpreted as different types depending whether a
data access is made to a REDEFINED variable or to the data declaration that has
been aliased by the REDEFINE.
Most tools either drop the aliasing, generate
broken code (requiring manual intervention to fix), or generate extremely inefficient
and hard to maintain code that continually converts between natural target language
data types and the byte memory representation at high runtime cost.
How DMS handles itW
All data declarations, whether REDEFINED or not, have an appropriate native target data type (int, string, ...) chosen to represent it.
For data declarations that are not REDEFINED, DMS generates an appropriate target data declaration directly, as one would desire.
For REDEFINED data, DMS generates a class representing the chosen target type with set/get data accessors for that type.
To preserve COBOL semantics, sometimes the target native type of the REDEFINED declaration must be converted to/from underlying byte arrays; this would be expensive if every access did this. For most (repeated) accesses, the byte representation isn't needed; a cached value in the data class is updated/returned with very little overhead.
Together these translator actions ensure that the translated program code is very readable because it always operates on target native types, regardless of REDEFINES, and that data accesses are extremely fast.
GO TO and unstructured control flow
The Problem770s and 80s COBOL code
often leans on GO TO. AI tools translate them as Java labels and jumps, except Java doesn't
have a GOTO at all. Output is broken or worse, looks like it works.
How DMS handles itA formal control-flow restructuring pass identifies
the loops and conditionals the unstructured code is expressing. Generated Java
and C# have no labels and no jumps.
EVALUATE TRUE is not a switch statement
The ProblemEVALUATE TRUE with
multiple WHEN clauses is not a switch on a value. Each WHEN is an independent boolean. Almost
every AI tool we've tested fails this.
How DMS handles itThe pattern
generates if-else if-else chains. Order of evaluation is preserved. Fall-through semantics are
preserved. Java behaves like the COBOL on every edge case.
Hierarchical indexed files based on VSAM, IMS, Enscribe
The ProblemStandard COBOL offers indexed
files which implicit schemas defined partly COBOL record data declarations, and partly by
vendor-specific data schemas. None of these maps directly to a modern relational target.
How DMS handles itWe build custom translations of the vendor
databases schemas into relation schemas. We analyze how every program reads and writes the data,
and convert accesses to JPA, ODBC, JDBC or Hibernate. JSON columns or polymorphic mappings preserve
information where REDEFINES blocks have a clean fit.
Large monolithic COBOL programs and COPY lib preservation
The ProblemA naïve conversion converts a
COBOL program into a giant target language class with COPY libs expanded in place.
The sheer scale makes maintenance hard. Especially hard is needing to modify the shared
record that most COPY libs represent, because the record has been cloned into the many COBOL
programs that use it.
How DMS handles itDMS translates each program P into a main class P
containing main program scalar variables and methods representing sets of code
paragraphs as determined by PERFORM A TO Z statements. The main class is supported
by a set of additional classes each representing records declared in the main program
and/or COPY libs used. Duplicate COPY classes across translation units are merged.
The result is a much more structured translation with COPY libs objectified.
Very long COBOL identifiers / access paths
The ProblemCOBOL programs tend to be written using long identifiers for paragraph/section names, and all identifiers defined in data records. Often these identifiers share long prefixes that match the name of the containing program. Preserving these names completely produces rather long source lines.
How DMS handles itThe client can provide DMS with a list of "renames" to replace arbitrary names with shorter, more meaningful names. DMS will accordingly revise those names as it translates.
Special shared-prefix shortening can be enabled; this tends to provide much shorter access paths in the code.
CICS to Spring transactions
The ProblemEXEC CICS commands handle transactions, security, and concurrency on the mainframe. Tools that work file-by-file lose the transactional boundaries.
How DMS handles itEXEC CICS READ, WRITE, REWRITE translate to Spring Data calls with @Transactional annotations. Locking semantics are preserved. Pseudo-conversational patterns become Spring controllers.
JCL to Spring Batch
The ProblemJCL defines batch dependencies, restart logic, error handling, and dataset routing. Nobody talks about it until they're 6 months in and the batch window won't close.
How DMS handles itJob streams convert to Spring Batch with the same step dependencies, restartability, and conditional flow. You get a maintainable Spring Batch project, not shell scripts.