将传统的Cobol/PL1迁移到Java的经验

5

原问题: 我想知道有没有人将大型Cobol/PL1代码库迁移到Java的经验?

这个过程有多自动化,输出结果有多易于维护?

从事务性到面向对象的转变如何进行?

在此过程中学到了什么经验教训或者有哪些资源/白皮书可以提供帮助?


7/7编辑: NACA方法确实很有趣,能够在发布JAVA版本前继续对COBOL代码进行业务日常更改,对于任何组织都具有优点。

对于拥有大量代码库的大型组织来说,以与COBOL相同布局的过程化Java来给程序员一种舒适感,同时熟悉Java语言是一个有效的论据。正如@Didier指出的,每年省下的300万美元为任何BAU变化提供了慷慨的填充,以便不断地对代码进行重构。正如他所说,如果你关心你的员工,你会找到一种方法让他们保持快乐,同时逐渐挑战他们。

我认为@duffymo的建议存在问题:

最好尝试真正理解问题的根源,并将其重新表达为面向对象的系统

如果您有任何BAU变化正在进行,那么在编写新的OO系统的长期项目生命周期中,您最终会在双倍的时间内进行编码和测试。这是NACA方法的一个重大优点。我曾经将客户端/服务器应用程序迁移到Web实现,这是我们遇到的主要问题之一,由于BAU变化不断变化,导致了需求不断变化。这使得项目管理和调度成为真正的挑战。

感谢@hhafez的贡献,他的经验被很好地描述为“类似但略有不同”,并且对从Ada自动迁移到Java的代码具有相当满意的经验。

感谢@Didier的贡献,我仍在研究你的方法,如果有任何问题,我会给你留言。


1
NACA似乎很有趣,在JAZOON会议上有详细的介绍。请看下面我的更新。 - Jim Ferrans
1
@Ira和@MadMurf:我们在这里看到的是编写两种根本不同的语言之间的源代码转换器有多么困难的证据。翻译器必须通过原始语义来保持正确性,并且它必须使新代码能够追溯到旧代码,这意味着它不应该进行重构。它不能从过程化结构中神奇地引出面向对象的结构。他们的Java开发人员似乎非常优秀(例如,在处理Cobol数据类型声明时使用Builder模式)。这就是自动翻译的本质。 - Jim Ferrans
@Jim:面向对象编程很难;我不会争论从非面向对象代码中获得面向对象结果的问题,因为领域建模非常困难。但是你可以为底层技术的良好转换进行辩护。用Java编写的过程式代码仍然可以运行和维护,但不必在其中有任何源语言(例如COBOL)的迹象。我在这方面有一些经验:www.semanticdesigns.com/Products/Services/NorthropGrummanB2.html,那里的要求是“将业务规则保留在JOVIAL工程师手中(听起来很熟悉吧?)”。 - Ira Baxter
8年过去了,你最终对这个系统做了什么? - Ira Baxter
@IraBaxter 的预算发生了改变,导致“绕边缘选择”方案被实施。旧代码仍然存在并正在使用,因为多年来需要进行更改。现在已经实现了 Java RESTful 服务,但仍有 75% 的遗留代码在使用中。 - MadMurf
显示剩余4条评论
7个回答

7
更新 6/25: 一位朋友刚刚发现了NACA Cobol 到 Java 转换器。看起来非常有趣,它被用于将 4m 行 Cobol 翻译成 Java,且准确率达到了 100%。这是NACA 开源项目页面。我看到的其他转换器都是专有的,而且材料显然缺乏成功案例和详细示例代码。NACA 值得仔细研究。 更新 7/4: @Ira Baxter 报告说,Java 输出看起来非常类似 Cobol,这绝对是自动翻译的自然结果。我认为这可能需要逐步重写的方法。 更新 2/7/11: @spgennard 指出,JVM 上有一些 Cobol 编译器,例如 Veryant 的 isCobol Evolve。这些可以用来帮助逐步过渡代码库,尽管我认为 OP 更感兴趣的是自动化源代码转换。
我会非常谨慎对待这个问题。(我曾经为一家公司工作,该公司自动纠正 Cobol 和 PL/I 程序以适应 Y2K,并编写了将多种方言的 Cobol 转换成我们中间分析形式的前端编译器,以及代码生成器。)我的感觉是,你最终会得到一个仍然不够优雅且难以满意地使用的 Java 代码库。你可能会遇到性能问题、依赖于供应商提供的库、生成的代码有缺陷等问题。你肯定会承担巨大的测试费用。

从头开始设计一个新的面向对象的设计可能是正确的方法,但你也必须仔细考虑代码库所代表的几十年的存储知识。通常有许多微妙之处,你的新代码可能会忽略。另一方面,如果你很难找到维护遗留系统的员工,你可能别无选择。

一个渐进的方法是先升级到 Cobol 97。这添加了面向对象,因此在添加新功能时可以逐个重写和重构子系统。或者你可以用全新编写的 Java 替换单个子系统。

有时候,您可以使用现成的软件替换组件:我们帮助过一家非常大的保险公司,他们仍然使用自己在上世纪50年代创建的遗留语言编写的200万行代码。我们将其中一半转换为符合Y2K标准的遗留语言,而他们则用从外部供应商购买的现代工资系统替换了另一半。

1
NACA的输出看起来很像COBOL,因为他们将翻译器设计得非常简单,例如,他们只是使用Java代码实现COBOL语义。你完全可以产生更好的翻译。例如,NACA实现可能会保留来自主机的十进制数据类型并实现十进制算术等,因此在COBOL中ADD A TO B被翻译成类似于(NACA说“每个语句一个语句”)B.COBOLDECIMALADDTO(A)的东西。推断出数据类型总是纯整数时应该很容易生成A+=B;,就像人们所期望的那样。 - Ira Baxter
1
如果你只想移动COBOL动词,这可能有效。作为一般规则,在新世界中,你必须模拟许多其他应用程序依赖项:交互管理(CICS),文件访问方法(ISAM?DB2?...),屏幕I/O(3270?24x80?),作业管理等等,这些“COBOL翻译器”无法处理。你不能“只是重新编译”;你必须将代表遗留依赖关系的习语翻译成等效的东西。这通常是不容易的。请参见https://dev59.com/anA75IYBdhLWcg3wJFYL#3460977。 - Ira Baxter
1
稍晚地补充一下:NACA的结果并不是“翻译的自然结果”。OP说:“我怀疑我们找不到更好的翻译工具了。” 我们公司制作了一个我们认为更好的翻译工具。您可以在此处检查其输出:https://www.semanticdesigns.com/Products/Services/COBOLMigration.html?site=convert-COBOL-to-Java.com?site=StackOverflow - Ira Baxter

4

我们的目标是获得尽可能接近原始COBOL代码的初始Java代码,以便于人员迁移:他们可以在完全相同的结构中找到他们用COBOL编写的好老应用程序。

我们最重要的目标之一是留住最初的开发人员:这是我们找到的实现方法。当应用程序迁移到Java时,这些人可以开始将其进一步开发/重构为更面向对象。

如果您不关心人员迁移,可以使用其他策略。

这种1对1的转换也使得100%自动化转换更加简单快速:好处是我们让经常性节约(每年3百万欧元)更快地实现了:我们估计需要12-18个月。这些早期的节约显然可以重新投资于面向对象的重构。

如有需要,请随时联系我:didier.durand@publicitas.com或mediaandtech@gmail.com

Didier


3
我刚刚查看了NACA的页面和文档。根据他们的文档:
“生成的Java使用类似于Cobol的语法。它尽可能接近原始Cobol语法,当然在Java语言的限制内。 生成的代码不像传统的本地Java,并且从应用程序的角度来看并不是面向对象的。 这是一种设计上的强烈选择,以实现Cobol开发人员平稳过渡到Java环境。目标是将业务知识留在编写原始Cobol程序的人手中。”
我没有看到示例,但是引用给出了强烈的结果味道。它是用Java编写的COBOL。
您始终可以通过在目标语言中编写解释器来构建“翻译器”。在我看来,这是一种绝对可怕的翻译语言的方式,因为您无法获得新语言的价值,而且仍然必须具有旧语言的知识才能保持结果活动。(难怪这个东西被称为“转码器”;我以前从未听说过这个术语)。
这个噱头的论据是要摆脱大型机的成本。有证据表明,转换后的程序的工作成本并没有超过节省的成本吗?我怀疑真相是运营人员通过摆脱大型机降低了成本,而他们对维护任务变得更加昂贵毫不在意。虽然这对于运营人员来说可能是合理的选择,但对于整个组织来说,这是一个愚蠢的选择。
上帝保佑那些成为这个工具受害者的人。
编辑于2010年5月:我找到了NACA输出的示例之一;其中一个他们的测试用例。这是绝对华丽的JOBOL。很幸运他们“保留”了COBOL程序员并且不想雇用任何Java程序员。当您阅读此内容时,请务必记住这是Java代码。
/*
 * NacaRTTests - Naca Tests for NacaRT support.
 *
 * Copyright (c) 2005, 2006, 2007, 2008 Publicitas SA.
 * Licensed under GPL (GPL-LICENSE.txt) license.
 */

import idea.onlinePrgEnv.OnlineProgram;
import nacaLib.varEx.*;

public class TestLong extends OnlineProgram
{
  DataSection WorkingStorage = declare.workingStorageSection();

  Var W3 = declare.level(1).occurs(10).var();
  Var V9Comp010 = declare.level(5).pic9(10).var();
  Var V9Comp014V4 = declare.level(5).pic9(14, 4).var();
  Var VX10 = declare.level(5).picX(10).var();

  public void procedureDivision()
  {
    setAssertActive(true);

    move("9876543210", VX10);
    assertIfDifferent("9876543210", VX10);

    move(VX10, V9Comp010);
    long l = V9Comp010.getLong();
    assertIfFalse(l == 9876543210L);

    multiply(1000, V9Comp010).to(V9Comp014V4);
    assertIfFalse(9876543210000L == V9Comp014V4.getLong());

    String cs = V9Comp010.toString();
    cs = V9Comp014V4.toString();
    assertIfDifferent("9876543210000.0000", V9Comp014V4);

    inc(V9Comp010);
    assertIfFalse(9876543211L == V9Comp010.getLong());

    CESM.returnTrans();
  }

孩子们:这只有专业人员才能做。请勿在家中尝试。

除此之外,在COBOL/PL1中嵌入式SQL处理非常易读,但当它转换为Java变体时,它不够易读且需要更多的处理。嵌入式SQL Java框架(SQLJ)并不是很流行,似乎也不能使用。 - cobp
@cobp:您似乎反对将主机语言翻译成Java会导致更加笨拙的SQL语句实现。我并不认为这是必要的。然而,这个特定的答案是针对一个特别提出的“转码器”的,其程序过程部分的输出是非常丑陋/难以维护的情况;在这种情况下,已翻译的SQL是否丑陋并不重要。 - Ira Baxter
@IraBraxter 的 SQL 部分并不丑陋或难以维护。我认为相比 Java,它有更多语法糖。此外,如果最初是用 Java 开发的,可以使用 ORM 框架等其他方式来实现它。 - cobp

2
我的经验与此类似,但略有不同。我们有一个大而老的Ada代码库(15年内0.5Mloc),最近转换为Java。这项工作被外包给一家公司,他们提供了自动/手动混合转换。他们还进行了测试,以验证Ada和Java系统的行为是否相同。
其中一些部分是用Ada 95编写的(即具有OOP的可能性),但大多数部分不是。
现在,是的,代码不符合Java的编写标准,但我们自那时以来一直成功地使用它(已有18个月),没有重大问题。我们获得的主要优势是现在可以找到更多开发人员来维护我们的代码库,并具备生产可维护代码的技能。(任何人都可以开发Ada,但像其他语言一样,如果你没有它的经验,你可能会得到难以维护的代码)。

转换的原因是什么?Ada似乎是一种很好的语言。 - Demi

2
从风险规避的角度来看,NACA方法是有道理的。但重复使用他们的工具可能不太合适。他们利用开发工具来让团队熟悉Java和Linux。
NACA转换的结果可能并不好,也不是面向对象的,这会使得招聘新人变得更加困难。但它是可测试的,可以重构,并且可以插入更好的转换器。
【编辑】 Ira,你似乎不太关注风险。
将COBOL程序员送去上Java课程并不能让他们编写可用的面向对象代码。那需要几年时间。在此期间,他们的生产力将非常低,你可以基本上把他们第一年写的所有代码都扔掉。此外,你将失去10-20%的程序员,他们不愿或不能进行过渡。很多人不喜欢回到初学者的状态,这将影响到等级制度,因为有些程序员比其他人更快地掌握了新语言。
NACA方法使企业能够继续运作,对组织没有不必要的压力。转换的时间表是独立的。拥有一个独立的、由面向对象专家编写的Java翻译器,允许旧团队逐渐接触Java。编写测试用例可以增加新Java团队的领域知识。
真正的面向对象系统是翻译器,那是插入更好翻译器的地方。使其易于这样做,你就不必触及生成的代码。如果生成的代码足够丑陋,那么这将自动发生:
  • 老程序员将会更改COBOL输入;
  • 新Java程序员将更改翻译器。
【运行一次翻译器】 是一个糟糕的策略。别这样做。如果你需要编辑生成的代码,请保持一个映射关系。这可以自动化。在Smalltalk图像中进行这些操作要容易得多,但你也可以使用文件进行操作。有许多经验丰富的人维护着对同一工件的不同视图:芯片设计师就是其中之一。
翻译器应该被仪器化,以便你可以创建每日的计数,例如:
  • COBOL输入组件;
  • OO Java输入组件;
  • COBOL风格的输出组件;
  • OO风格的输出组件。
你可能想阅读: Peter van den Hamer & Kees Lepoeter(1996)Managing Design Data:CAD框架,配置管理和数据管理的五个维度,IEEE会议录,Vol.84,No.1,1996年1月。

[移动Cobol平台] 从大型机上的Cobol到Windows/Linux上的Cobol可能是NACA团队的可行策略,但问题在于是否转向Java。如果长期目标是拥有现代化的面向对象系统,并且要尽可能减少运营风险,那么NACA的方法是正确的。但这只是第一步,接下来还需要进行大量重构。


3
唯一避免的风险是现有的COBOL程序员是否能够在转换后的系统上工作。如果您认为COBOL程序员不是脑残,那么这看起来并不像是一个很大的风险,而且为了避免使用COBOL作为Java所浪费的资金,他们可将所有COBOL程序员派往Java培训班。关于“插入更好的翻译程序:”一旦转换完成,你就不能这样做。人们会更改转换后的代码,现在你无法返回原始状态。 - Ira Baxter
4
“真正的面向对象系统是翻译器……”那又怎样呢?一旦所有代码都被转换,几乎肯定会在翻译后的代码上进行维护。您永远不会再次运行翻译器,因此它是无关紧要的。现在,您可能会建议方案坚持保留原始的COBOL,并让COBOL程序员在其上工作;这是一种模型,但考虑到支持该COBOL代码的主机已经不存在,我认为这种情况不太可能发生。一旦翻译完成,我无法想象维护旧的COBOL代码的价值所在。 - Ira Baxter
3
如果您打算保留COBOL应用程序代码以便可以重复运行翻译器,那实际上您正在将应用程序保留在COBOL中。在这种情况下,正确的答案是将主机上的COBOL翻译为目标系统上的COBOL(例如MS的COBOL.net或MicroFocus COBOL)。如果您想要在另一个平台上使用而还想继续支持主机COBOL编程,那么这个想法简直超出了我的理解。如果您不打算继续使用COBOL,则保留COBOL到其他任何语言的翻译器同样没有意义。 - Ira Baxter

2
我很惊讶没有人提到Semantic Design的DMS软件重构工具包。我曾经研究过COBOL转换。当时我正在研究“自动编程”。在编写翻译器之前,我查看了该领域中的一些先前的努力和产品。Semantic Designs基于GLR的工具是最好的。那是很多年前的事了。当时,该工具将COBOL转换为现代语言,重构它,美化它等等。这是它的链接。

http://www.semdesigns.com/Products/DMS/DMSToolkit.html

他们仍然存在。他们扩展了这个工具,它更加通用。它可能会帮助那些进行自动转换或自定义转换工具的人们。它被设计成可以像Stephan指出的那样可扩展和调整。感谢Cyrus提到的SoftwareMining。如果我将来遇到COBOL迁移,我也会研究一下它们。

1

你在谈论重构。好的一面是全世界有很多人试图做到这一点。坏的一面是关于遗留应用程序重构存在很多问题:从缺失源代码到编译器构造和图论领域的复杂算法。

自动翻译的想法非常流行,直到你尝试转换某些东西。通常结果是可怕的且难以维护。它比原来复杂的应用程序更难以维护。在我看来,每个允许从旧语言自动翻译到现代语言的工具都非常市场化:它准确地说出了人们想要听到的话“将您的应用程序从...翻译成Java一次,然后忘记它!”,然后你购买了一个合同,然后你意识到你非常依赖这个工具(因为你不能在没有它的情况下对应用程序进行任何更改!)。

另一种方法是“理解”:这种工具可以让你非常详细地了解你的遗留应用程序。你可以用它来进行维护、文档编写或在新平台上重新发明。

我对现代化工作台在Microfocus去年购买并将开发移至另一个国家之前的历史有一些了解。它拥有大量复杂的分析工具和支持的目标语言数量(包括Java)。但是没有客户真正使用自动代码生成,因此生成部分的开发被冻结。据我所知,PL/I支持大多已实现,但从未完成。但你仍然可以尝试,也许这就是你要寻找的。


那么你就会明白,你非常依赖于工具?不是一般情况。通常翻译工具只用来转换代码一次,然后就被丢弃了;进一步的开发工作都是在翻译后的代码上进行的。更合理的反对意见是生成的代码质量(这是对NACA的反对意见),而实现不良的工具确实存在这个问题。使用工具可以实现良好的翻译。如果工具不是专门为单个迁移而构建的,那么长期的工具会随着时间的推移而加强其基础。 - Ira Baxter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接