Even in (relatively) small volumes, HLASM is a serious problem
In most mainframe shops, the volume of HLASM code is small compared to COBOL or PL/I. Even so, as little as 30’000 lines of assembler code will cause unexpected delays and budget overruns. If one considers rewriting it, reverse engineering its behavior requires specific and expensive expertise. Besides, it can easily take months of testing and debugging before the new code can be put in production with an adequate level of reliability, availability and security. The automated tools that claim to translate assembler into Java, C# or COBOL have failed to deliver, and that is even before anyone considers maintaining the resulting code. Your one and only viable option is to compile your ASM 370 code on the destination platform “as is” on the mainframe.
The volume of COBOL code is not the problem
Early in your migration project, you will experience the delusional and comfortable feeling of having compiled 90% of your COBOL code. The devil is in the details though: the remaining 10% can take months or even years to fix. Issues such as IBM dialects, preprocessor support, built in support for CICS and SQL, EBCDIC mode, arithmetic precision may be found in a small fraction of your portfolio but disproportionally impact the entire migration project.
JCL is business logic
JCL is not just an orchestration facility, a mere technicality that can be easily ignored. JCL contains the business logic for complex business processes, and must not be discarded as a mere technicality. It cannot be rewritten without an extensive study of its current architecture, how the various batch jobs are interconnected by scheduling, etc. As much as one wants to get rid of JCL as an antiquated technology, dealing with it raises the same issues as any other piece of legacy code, with amazingly similar solutions, including keeping it as it is if volume and/or complexity does not allow for redevelopment.
I can do without a CICS emulator
CICS on the mainframe is made of two parts: language extensions in your COBOL, PL/I and Assembler programs, and an infrastructure to support the CICS services when they are called from within these programs. It is a major misconception to believe that this coupling cannot be avoided, and that a software system with CICS statements cannot be deployed without an expensive and inflexible full-featured CICS emulator. When free from 3270 interfaces (the infamous green screens) you can deploy complete CICS infrastructures in more scalable and cost-effective ways.
EBCDIC is a challenge
ASCII is the world standard, but EBCDIC rules the mainframe world. Converting your data as part of the migration process is tempting, but in practice, raises more issues than you should feel comfortable with: redefinition, collating sequences, and more. The amount of manual changes, and the corresponding test workload increase dramatically, up to a point where the rehosting project goes from being a mere technical endeavor to a complete change of functional behavior, with a very different risk profile. If you keep EBCDIC as the *internal* data representation (data should definitely not be stored in EBCDIC in relational databases!) you eliminate a serious risk factor.
No serious migration project can be deployed without a plan to make it incremental
No amount of testing will ever guarantee perfection. Parts of the migration can and will go wrong for a variety of reasons, and you cannot count on luck alone for your project to succeed. You must survive the bumps that will occur. You must be able to phase your project, and have the ability to revert each of these phases if anything happens.
More than likely, your management will not take the risk of a migration project guaranteed by testing alone. And if they do accept this risk, the blame for any mishap will be on you. You were the one who claimed that testing would do.
PL/I is a pain point
For all practical purposes, PL/I is more like assembler than like COBOL:
It can be confusingly hard to understand and maintain
Converting it automatically or manually to any language fails more often than not
Even in small volumes, it is a serious challenge
And just as for assembler, compiling it in its current form is the safest route, both in terms of cost effectiveness and support for a phased-based approach, where the same source code must run on both the source and the target platform for a transitional period.