现代化历险记:策略+将COBOL转换为Java的示例
在Keyhole Software,我們?cè)诤艽蟪潭壬鲜且患椰F(xiàn)代化公司。 我們擁有一些顧問(wèn),他們專(zhuān)門(mén)研究將舊的代碼遷移到新的,翻新的殘舊代碼庫(kù),并為大多數(shù)已經(jīng)被供應(yīng)商鎖定的企業(yè)設(shè)計(jì)更光明的未來(lái)。
作為這些經(jīng)驗(yàn)的有趣的副作用,我們遇到了一些重復(fù)的模式和策略,以了解如何實(shí)現(xiàn)遺留系統(tǒng)的現(xiàn)代化。
在此博客中,我們將介紹一種看起來(lái)非常流行的策略Re-Platforming ,并將用我們開(kāi)發(fā)的Keyhole Labs產(chǎn)品進(jìn)行演示。 這篇文章的基本流程是:
- 現(xiàn)代化概論
- 重新平臺(tái)戰(zhàn)略的高層定義
- 使用Keyhole語(yǔ)法樹(shù)變壓器進(jìn)行重新平臺(tái)化的示例
- 結(jié)束語(yǔ)
- 摘要
“我要進(jìn)行一次現(xiàn)代化……不等,也許要兩個(gè)……”
當(dāng)我們第一次圍繞現(xiàn)代化主題吸引客戶(hù)時(shí),我們會(huì)看到他們?cè)诖诉^(guò)程中實(shí)際想要完成的工作的定義各不相同。 這些范圍包括從大型機(jī)應(yīng)用程序退出,從ESB /經(jīng)典SOA架構(gòu)過(guò)渡到基于云的PaaS實(shí)施,再到從供應(yīng)商鎖定/分層架構(gòu)遷移到DevOps /微服務(wù)架構(gòu)。
隨著十年前最近更新其技術(shù)堆棧的公司遇到成功運(yùn)營(yíng)或成長(zhǎng)的一些關(guān)鍵問(wèn)題,所有這些情況的發(fā)生頻率越來(lái)越高:
- 部署問(wèn)題:所有內(nèi)容都必須作為一個(gè)單元進(jìn)行部署,這是一個(gè)痛苦的過(guò)程,并且/或者與其所有基礎(chǔ)架構(gòu)緊密耦合
- 可伸縮性問(wèn)題:可伸縮性的垂直極限受到了打擊–這意味著機(jī)器無(wú)法足夠快地變大以應(yīng)對(duì)容量的增加
- 性能問(wèn)題:系統(tǒng)中消息/事務(wù)的數(shù)量正在增加延遲,在某些情況下會(huì)導(dǎo)致級(jí)聯(lián)故障
- 資源問(wèn)題:使用此系統(tǒng)的工程師和計(jì)算機(jī)科學(xué)家本來(lái)就不在或即將退休,并且不再在學(xué)校教授編程語(yǔ)言
因此,請(qǐng)進(jìn)入現(xiàn)代化計(jì)劃。 讓我們首先回顧一下Re-Platforming策略及其優(yōu)缺點(diǎn)。
這就像修理我的靴子嗎?”
重新平臺(tái)有時(shí)也稱(chēng)為升降機(jī)。 從根本上講,重新平臺(tái)是將一種代碼語(yǔ)言轉(zhuǎn)換為另一種代碼語(yǔ)言,即進(jìn)行翻譯。 作為現(xiàn)代化策略,這意味著將較舊的代碼語(yǔ)言轉(zhuǎn)換為較新的代碼語(yǔ)言。
由于各種原因,大型機(jī)在一些大型企業(yè)中仍然很普遍,因此,像COBOL這樣的舊代碼庫(kù)也仍然存在。 擺脫這些較舊的代碼庫(kù)和大型機(jī)的原因通常是以下之一:
- 資源問(wèn)題(如上所述):大型機(jī)程序員正變得稀缺,并且這些語(yǔ)言集在任何現(xiàn)代課程中都沒(méi)有涉及。 招聘新開(kāi)發(fā)人員比較困難,尤其是在快速變化和技術(shù)選擇日趨廣泛的情況下。 更少的員工愿意研究某些被淘汰的技術(shù)。
- 對(duì)于任何規(guī)模的企業(yè)而言,大型機(jī)都是一筆巨額費(fèi)用,而垂直增長(zhǎng)則是唯一的增長(zhǎng)選擇,有時(shí)這是昂貴的。
大多數(shù)現(xiàn)代體系結(jié)構(gòu)中常見(jiàn)的災(zāi)難恢復(fù)和高可用性策略可能會(huì)對(duì)大型機(jī)造成成本上的限制。 - 程序語(yǔ)言構(gòu)造(OOP,函數(shù)式編程,反應(yīng)式編程等)中不能輕易利用更新的編程模式-因此限制了選擇的范圍。
- SDLC的變化–即從瀑布過(guò)渡到敏捷過(guò)程以保持競(jìng)爭(zhēng)力。
因此,長(zhǎng)話(huà)短說(shuō)-說(shuō)“重新平臺(tái)化”實(shí)際上是什么意思?
在此過(guò)程中,將分析較舊的代碼庫(kù)以確定代碼庫(kù)中的語(yǔ)法或模式。
一旦定義了語(yǔ)法樹(shù)或一組代碼模式,便會(huì)通過(guò)某些單步或多步編譯器軟件運(yùn)行原始代碼庫(kù)(即COBOL),以將舊代碼轉(zhuǎn)換為所需的最終狀態(tài)-通常是Java, C#或更高版本的等效語(yǔ)言。
從業(yè)務(wù)角度來(lái)看,這可能非常有吸引力。 無(wú)需讓產(chǎn)品所有者和開(kāi)發(fā)人員組成團(tuán)隊(duì)來(lái)逐步用新語(yǔ)言重新編寫(xiě)每個(gè)舊代碼位,此方法有望通過(guò)幾次按鈕操作來(lái)完成所有繁重的工作。 聽(tīng)起來(lái)不錯(cuò)!
好吧,教授,請(qǐng)稍等片刻–在繼續(xù)之前,這種方法存在一些固有的問(wèn)題,需要提到。 最難的事情是:
代碼翻譯不一定能解決技術(shù)問(wèn)題!
在某些情況下,這些舊代碼庫(kù)可能已經(jīng)存在了20多年。 這可能是20多年的錯(cuò)誤決定,或者是特定于大型機(jī)的決策被納入您的代碼中。
所有的翻譯過(guò)程都將為您提供那些潛在的代碼地雷,這些地雷現(xiàn)在正在使用新的語(yǔ)言,它們可能無(wú)法從大型機(jī)的慷慨和能力中受益。
代碼看起來(lái)可能比大型機(jī)差!
在此過(guò)程中運(yùn)行代碼有時(shí)可能最終看起來(lái)像是被削木機(jī)扔掉了。 一些大型機(jī)和遺留代碼構(gòu)造/行為無(wú)法很好地轉(zhuǎn)換或根本無(wú)法轉(zhuǎn)換成較新的代碼庫(kù)。 (例如:在一個(gè)最近的客戶(hù)處,我們找到了一個(gè)示例,其中在一個(gè)代碼庫(kù)中x / 0的數(shù)學(xué)運(yùn)算返回0!)
即使代碼可以轉(zhuǎn)換并看起來(lái)不錯(cuò),這也不意味著它將始終運(yùn)行!
僅僅翻譯成另一種語(yǔ)言并不能保證執(zhí)行成功–一次成功的翻譯通常并不意味著語(yǔ)法錯(cuò)誤。
可能需要一些調(diào)整,其他基礎(chǔ)結(jié)構(gòu)來(lái)幫助代碼工作和構(gòu)建。
運(yùn)行中!=執(zhí)行中
同樣,如果我們讓它運(yùn)行并構(gòu)建起來(lái),那么在我們的試點(diǎn)轉(zhuǎn)換中,一切似乎都很棒。 一旦我們處理了數(shù)百萬(wàn)筆交易并進(jìn)行了記錄,您就會(huì)發(fā)現(xiàn)存儲(chǔ)桶中的所有漏洞。
這個(gè)過(guò)程很可能不會(huì)降低復(fù)雜性!
在此過(guò)程中,您很可能會(huì)從處理其所有復(fù)雜性的過(guò)程(在某些情況下幾乎沒(méi)有或沒(méi)有I / O損失)過(guò)渡到對(duì)資源的??慷慨解囊。
將這些代碼庫(kù)轉(zhuǎn)移到較新的語(yǔ)言中,通常涉及一些關(guān)注點(diǎn)分離:
- 數(shù)據(jù)訪(fǎng)問(wèn)層與嵌入式SQL語(yǔ)句相對(duì)
- 與基于文件的數(shù)據(jù)存儲(chǔ)相反的潛在新關(guān)系數(shù)據(jù)存儲(chǔ)
- 與UI代碼相反的表示層
- 服務(wù)/業(yè)務(wù)邏輯層作為其自己的層
可能需要一些其他基礎(chǔ)架構(gòu)來(lái)處理大型機(jī)免費(fèi)提供的功能
像消息傳遞,容器或虛擬機(jī)編排,隊(duì)列和AD / LDAP / OAuth集成等。
因此,現(xiàn)在您可能會(huì)感覺(jué)就像您剛走進(jìn)一家醫(yī)藥商業(yè)廣告,我在那兒說(shuō)道:
“這種小藥丸可以解決您所有的背痛和黃色的趾甲問(wèn)題。 潛在的副作用可能包括嘔吐,眼睛和/或耳朵出血,暫時(shí)性視力喪失,自發(fā)性脫發(fā)以及對(duì)字母“ A”的痛苦敏感性。”
但是,如果您專(zhuān)注于以下方面,這可能是一個(gè)成功的旅程:
如果您選擇一個(gè)可以將語(yǔ)法樹(shù)用于初始轉(zhuǎn)換的過(guò)程,則……
您只需調(diào)整語(yǔ)法并重新運(yùn)行即可快速調(diào)整和調(diào)整更新后的輸出。
有時(shí),基于模式的轉(zhuǎn)換是唯一的選擇。 但是,在許多情況下,可以生成語(yǔ)法樹(shù)–然后您只需調(diào)整語(yǔ)法即可,而不是一次性調(diào)整輸出或單個(gè)模式。
Keyhole的Syntax Tree Transformer及其專(zhuān)有的COBOL語(yǔ)法分析器基于語(yǔ)法,并且可以做到這一點(diǎn)!
這是使您分階段實(shí)施的可行選擇。
特別是如果您的組織沒(méi)有人員來(lái)處理可能將數(shù)千個(gè)程序轉(zhuǎn)換為新堆棧的工作。
通過(guò)在短時(shí)間內(nèi)轉(zhuǎn)換所有舊代碼,您可以更快地淘汰舊技術(shù)。 然后,您可以重新分配這些資源,以分析和重新編寫(xiě)或清理具有最大業(yè)務(wù)價(jià)值和ROI的代碼部分。
這使組織可以對(duì)業(yè)務(wù)真正重要的方面做出更有目的的決策。
提供對(duì)您的代碼庫(kù)中應(yīng)用的業(yè)務(wù)邏輯的寶貴見(jiàn)解和分析。
在某些情況下,業(yè)務(wù)邏輯可能與代碼庫(kù)一樣古老,并且不再適用。 大多數(shù)客戶(hù)從中發(fā)現(xiàn)了很多價(jià)值,最終僅通過(guò)分析活動(dòng)就將他們的代碼庫(kù)減少了10-25%。
有機(jī)會(huì)引入DevOps作為轉(zhuǎn)換的一部分。
根據(jù)所需的代碼最終狀態(tài),在轉(zhuǎn)換過(guò)程之外,有機(jī)會(huì)引入DevOps作為轉(zhuǎn)換的一部分可能會(huì)有所幫助。 有時(shí),“有能力”站起來(lái)使用一些工具或?qū)嵤┬铝鞒套罱K會(huì)成為注入最佳實(shí)踐的機(jī)會(huì),而無(wú)需經(jīng)歷過(guò)多繁瑣的工作或走閘。
這些新的流程和工具可以被業(yè)務(wù)的其他領(lǐng)域所利用,并通過(guò)提高敏捷性和引起某些文化轉(zhuǎn)變來(lái)增加價(jià)值。
這個(gè)過(guò)程可以是短期預(yù)算雙贏(yíng)。
由于可以快速轉(zhuǎn)換和淘汰大型機(jī)和較舊的技術(shù),因此可以收回資本支出和維護(hù)成本。
使代碼進(jìn)入轉(zhuǎn)換后狀態(tài)的總開(kāi)發(fā)成本通常比手動(dòng)團(tuán)隊(duì)重寫(xiě)要小。
需要注意的是,從長(zhǎng)遠(yuǎn)來(lái)看,這可能是一項(xiàng)更昂貴的工作,因?yàn)楝F(xiàn)在新語(yǔ)言和基礎(chǔ)架構(gòu)中的代碼量很大–可能需要新的/額外的資源來(lái)維護(hù)和擴(kuò)展代碼庫(kù)。 –但是至少您應(yīng)該能夠找到它們!
該策略的要旨是:
如果您確定自己意識(shí)到該流程實(shí)際上可以做什么,并且選擇了一個(gè)強(qiáng)大的基于語(yǔ)法的工具(例如Keyhole語(yǔ)法樹(shù)變形器和我們的Parser –只是說(shuō)出來(lái)),那么您將獲得非常可預(yù)測(cè)的結(jié)果,從而可以節(jié)省預(yù)算和時(shí)間勝。
既然我們已經(jīng)了解了實(shí)施此策略的定義和利弊,那么實(shí)際上讓我們輕描淡寫(xiě)吧。 本文的用例將使用Keyhole語(yǔ)法樹(shù)轉(zhuǎn)換器從COBOL轉(zhuǎn)換為JAVA。
“讓我們已經(jīng)重新平臺(tái)!”
為了開(kāi)始這個(gè)示例,我們將從COBOL的樣本位開(kāi)始,該樣本已被我們的專(zhuān)有語(yǔ)法解析器轉(zhuǎn)換為JSON語(yǔ)法樹(shù)。 COBOL程序僅讀取DB2數(shù)據(jù)存儲(chǔ)并返回員工列表。 我們將不會(huì)顯示COBOL到JSON的實(shí)際轉(zhuǎn)換-而是從已經(jīng)轉(zhuǎn)換的COBOL程序開(kāi)始。
(對(duì)不起,這是博客文章的秘訣–因此,我們將以這種烹飪表演的方式,從昨晚已經(jīng)準(zhǔn)備好的火雞開(kāi)始!如果您對(duì)組織的流程感興趣或想要演示–請(qǐng)與我們聯(lián)系 )。
首先,我們需要介紹幾個(gè)設(shè)置項(xiàng)目:
- 對(duì)于此示例,您將需要克隆此存儲(chǔ)庫(kù): https : //github.com/in-the-keyhole/khs-syntax-tree-transformer
- 您將需要使用支持Docker的機(jī)器(Windows 10,各種版本的Linux,Mac)。 這是針對(duì)DB2示例的,如果您不想弄混Docker,則在回購(gòu)中有一個(gè)簡(jiǎn)單的COBOL示例。
- 這是一個(gè)人為的例子! 它并不意味著可以治愈任何疾病或在任何生產(chǎn)環(huán)境中使用! 它旨在演示該機(jī)制,并說(shuō)明如何從語(yǔ)法樹(shù)到Java應(yīng)用程序。
好的,讓我們開(kāi)始吧!
步驟1:
克隆存儲(chǔ)庫(kù)后,將其作為Maven項(xiàng)目導(dǎo)入Eclipse,STS或Intellij。
第二步:
使用JSON輸入文件的命令行參數(shù)和發(fā)出的Java包名稱(chēng)執(zhí)行main方法。 像這樣:
這將在項(xiàng)目目錄中生成一個(gè)發(fā)出的Program.java program :
package khs.res.example.Programpublic class Program {private Double CONST-PI = null; private Double WORK-1 = 0; private Double WORK-2 = 0; private Double PRINT-LINE = null; public void static main(String[] args) {Program job = new Program ();job.A-PARA ();} public void A-PARA () {WORK-1 = 123.46WORK-2 = WORK-2+2WORK-2 = WORK-3*3C-PARA()}public void B-PARA () {CONST-PI = Math.PI;EDT-ID = ZERO}public void C-PARA () {B-PARA()}}以下是程序?qū)⑹褂玫拿孛茚u汁分析器創(chuàng)建的輸入demo.json :
{"name" : "Program","typeName" : "CLASS","variables" : [ {"name" : "CONST-PI","typeName" : "VARIABLE","value" : null,"isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]}, {"name" : "WORK-1","typeName" : "VARIABLE","value" : "ZERO","isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]}, {"name" : "WORK-2","typeName" : "VARIABLE","value" : "ZERO","isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]}, {"name" : "PRINT-LINE","typeName" : "VARIABLE","value" : null,"isLocal" : false,"isWorking" : true,"isArray" : true,"fileLevel" : null,"variables" : [ {"name" : "EDT-ID","typeName" : "VARIABLE","value" : "SPACES","isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]}, {"name" : "FILLER","typeName" : "VARIABLE","value" : "' Perimeter '","isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]}, {"name" : "EDT-3-15-CIR","typeName" : "VARIABLE","value" : null,"isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]}, {"name" : "FILLER","typeName" : "VARIABLE","value" : "' Radius '","isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]}, {"name" : "EDT-3-15-RAD","typeName" : "VARIABLE","value" : null,"isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]}, {"name" : "FILLER","typeName" : "VARIABLE","value" : "' Pi '","isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]}, {"name" : "EDT-1-15-PI","typeName" : "VARIABLE","value" : null,"isLocal" : false,"isWorking" : true,"isArray" : false,"fileLevel" : null,"variables" : [ ]} ]} ],"functions" : [ {"name" : "A-PARA","typeName" : "FUNCTION","methods" : [ {"name" : "123.46TOWORK-1","typeName" : "METHOD","type" : {"name" : null,"typeName" : "MOVE","varName" : "WORK-1","value" : "123.46"}}, {"name" : "2TOWORK-2","typeName" : "METHOD","type" : {"typeName" : "ADD","value" : "2","var1" : "WORK-2","var2" : null}}, {"name" : "3GIVINGWORK-3","typeName" : "METHOD","type" : {"typeName" : "MULTI","value" : "3","var1" : "WORK-2","var2" : "WORK-3"}}, {"name" : "C-PARA","typeName" : "METHOD","type" : {"name" : "C-PARA","typeName" : "CALL"}} ]}, {"name" : "B-PARA","typeName" : "FUNCTION","methods" : [ {"name" : "PITOCONST-PI","typeName" : "METHOD","type" : {"name" : null,"typeName" : "MOVE","varName" : "CONST-PI","value" : "PI"}}, {"name" : "ZEROTOEDT-ID","typeName" : "METHOD","type" : {"name" : null,"typeName" : "MOVE","varName" : "EDT-ID","value" : "ZERO"}} ]}, {"name" : "C-PARA","typeName" : "FUNCTION","methods" : [ {"name" : "B-PARA","typeName" : "METHOD","type" : {"name" : "B-PARA","typeName" : "CALL"}} ]} ] }DB2示例
現(xiàn)在,在持久性方面邁出了一步,我們將轉(zhuǎn)換簡(jiǎn)單的DB2程序以演示使用DB2 Express的Java代碼。
這是示例DB2 Cobol應(yīng)用程序:
* -------------------------------------------------------------- * Selects a single employee into a record's detail fields, and * then displays them by displaying the record. * * Demonstrates Cobol-to-Java translation of a DB2 SELECT INTO * the detail fields of a parent record. * * Java has no native notion of a record aggregate. A SQL * SELECT INTO similarly lacks a record construct. * * Lou Mauget, January 31, 2017 * --------------------------------------------------------------IDENTIFICATION DIVISION.PROGRAM-ID. COBOLDB2.DATA DIVISION.WORKING-STORAGE SECTION.EXEC SQLINCLUDE SQLCAEND-EXEC.EXEC SQLINCLUDE EMPLOYEEEND-EXEC.EXEC SQL BEGIN DECLARE SECTIONEND-EXEC.01 WS-EMPLOYEE-RECORD.05 WS-EMPNO PIC XXXXXX.05 WS-LAST-NAME PIC XXXXXXXXXXXXXXX.05 WS-FIRST-NAME PIC XXXXXXXXXXXX.EXEC SQL END DECLARE SECTIONEND-EXEC.PROCEDURE DIVISION.EXEC SQLSELECT EMPNO, LASTNAME, FIRSTNMEINTO :WS-EMPNO, :WS-LAST-NAME, :WS-FIRST-NAME FROM EMPLOYEEWHERE EMPNO=200310END-EXEC.IF SQLCODE = 0DISPLAY WS-EMPLOYEE-RECORDELSEDISPLAY 'Error'END-IF.STOP RUN.使用我們的Antlr解析器已將其轉(zhuǎn)換為JSON語(yǔ)法樹(shù)。 使用khs.transformer.CommandLine.java對(duì)象將語(yǔ)法樹(shù)JSON轉(zhuǎn)換為以下Java應(yīng)用程序。
/*** Java source, file COBOLDB2.java generated from Cobol source, COBOLDB2.cbl** @version 0.0.3* @author Keyhole Software LLC*/ public class COBOLDB2 {private static Logger Log = LoggerFactory.getLogger("COBOLDB2");// SQLCAprivate int sqlcode;// Level 05private String v_ws_empno;// Level 05private String v_ws_last_name;// Level 05private String v_ws_first_name;// Level 01private InItem[] v_ws_employee_record = new InItem[]{ () -> v_ws_empno, () -> v_ws_last_name, () -> v_ws_first_name };// Procedure division entry:public static void main(String[] args) {try {COBOLDB2 instance = new COBOLDB2();instance.m_procdiv();} catch (Exception e) {e.printStackTrace();}}private void m_procdiv () throws Exception {final String sql = "SELECT EMPNO, LASTNAME, FIRSTNME FROM EMPLOYEE WHERE EMPNO=200310";final OutItem[] into = new OutItem[]{s -> v_ws_empno = (String)s,s -> v_ws_last_name = (String)s,s -> v_ws_first_name = (String)s};sqlcode = Database.getInstance().selectInto( sql, into );if ( sqlcode == 0 ) {Display.display( v_ws_employee_record );} else {Display.display( "Error" );}// EXIT ...System.exit(0);}}以下步驟描述了如何設(shè)置DB2以執(zhí)行該應(yīng)用程序。 DB2 Express在Docker容器中運(yùn)行。 沒(méi)有池連接。 這只是一個(gè)演示。 ?
Docker DB2 Express容器
確保您有權(quán)訪(fǎng)問(wèn)Docker 。
使用此Docker映像進(jìn)行初始DB2綁定: https : //hub.docker.com/r/ibmcom/db2express-c/
docker run --name db2 -d -it -p 50000:50000 -e DB2INST1_PASSWORD=db2inst1-pwd -e LICENSE=accept -v $(pwd)/dbstore:/dbstore ibmcom/db2express-c:latest db2start docker exec -it db2 bash創(chuàng)建運(yùn)行中的Docker DB2 Express容器守護(hù)程序,并登錄到bash會(huì)話(huà),如上所示。
發(fā)行su db2inst1
發(fā)出db2sampl (花一些時(shí)間來(lái)創(chuàng)建數(shù)據(jù)庫(kù)“ SAMPLE”)。
完成煙霧測(cè)試安裝后:
以Java運(yùn)行: khs.transformer.CheckDb2Connection
控制臺(tái)上顯示以下內(nèi)容:
一旦在Docker容器上安裝并驗(yàn)證了數(shù)據(jù)庫(kù),就可以執(zhí)行轉(zhuǎn)換后的Cobol / DB2到Java程序khs.res.db2demo.COBOLDB2.java 。 一旦執(zhí)行該程序,我們將得到以下輸出:
基本上是魔術(shù)!
同樣,這是人為的,但是我們采用了一個(gè)COBOL程序,該程序被轉(zhuǎn)換為JSON語(yǔ)法樹(shù),然后最終得到了一個(gè)Java應(yīng)用程序,該程序從DB2數(shù)據(jù)庫(kù)返回了我們的數(shù)據(jù)–正是COBOL程序所做的!
結(jié)論
希望在本文和上面的示例之后,我們都對(duì)重新平臺(tái)戰(zhàn)略有了更好的了解。 此策略是否適合您的組織是另一個(gè)話(huà)題(順便提一下,我們很樂(lè)意與您聯(lián)系)。
我要打動(dòng)的重點(diǎn)是,即使聽(tīng)起來(lái)很酷,代碼轉(zhuǎn)譯也不是遺留代碼狼的靈丹妙藥! 我還想告訴您,雖然充滿(mǎn)了危險(xiǎn),但是如果正確使用正確的方法并使用可靠的工具(ahem – 鎖Kong語(yǔ)法樹(shù)變壓器和解析),這可能是一個(gè)非常可行的策略。
“那么,我們?cè)谶@里完成了什么?”
總而言之,我們涵蓋了以下內(nèi)容:
- 現(xiàn)代化簡(jiǎn)介
- 回顧現(xiàn)代化的重平臺(tái)戰(zhàn)略
- 使用Keyhole語(yǔ)法樹(shù)變壓器的重新平臺(tái)示例
- 關(guān)于此策略的價(jià)值/風(fēng)險(xiǎn)的其他總結(jié)想法
我們肯定希望您能像我們一樣喜歡它。 請(qǐng),如果您有任何問(wèn)題或反饋,請(qǐng)?jiān)谙旅姘l(fā)布或直接與我們聯(lián)系。
謝謝,記得負(fù)責(zé)任地現(xiàn)代化!
資源/參考:該演示也可以在這里找到: https : //github.com/in-the-keyhole/khs-syntax-tree-transformer
翻譯自: https://www.javacodegeeks.com/2017/02/adventures-modernization-strategy-example-converting-cobol-java.html
總結(jié)
以上是生活随笔為你收集整理的现代化历险记:策略+将COBOL转换为Java的示例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: perl大骆驼和小骆驼_你好骆驼:自动文
- 下一篇: GitHub Research:超过50