尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ABAP Cloud开发实战:Released API与Deprecated Object的鉴定与改造指南

ABAP Cloud开发实战:Released API与Deprecated Object的鉴定与改造指南 在SAP圈子里泡得久了我越来越倾向一个判断一个ABAP开发是不是真正跨进了ABAP Cloud那道门不用看你会不会用RAP也不用看你手速快不快就看他拿到需求后开口问的第一句话。如果还是“我该调哪个函数”那基本还在传统开发的老路上如果换成“这个API到底能不能调”恭喜你已经切到新范式了。在ADT里做ABAP Cloud项目这几年我发现把Released API和Deprecated Object这两个概念从“听说过”变成“查得到、躲得开、用得稳”才是从“会用Eclipse”到“真正会做ABAP Cloud开发”之间最容易被忽略、又最能拉开差距的一段路。这篇文章不打算讲那些官方文档里写得明明白白的大理论而是把我在ADT里鉴定某段代码能不能在ABAP Cloud环境下活下来、怎么用Released API、怎么揪出Deprecated Object、以及一段传统ABAP代码要经历哪些改造才能重新上桌的完整过程掰开揉碎说一遍。适合在本地S/4HANA里写惯了SE80、正被Cloud-ready语法检查按在地上摩擦的ABAP开发也适合刚入门ABAP Cloud、想少走弯路的新人。1. ABAP Cloud 开发卡你的从来不是写代码而是“能用什么”1.1 为什么 Released API 是你的“开发许可证”在传统ABAP里SAP维护一个巨大的应用系统里面几十万类、函数、数据元素为了兼容历史版本很多东西明知道设计已经过时了也不会硬删。所以老开发写代码时养成一个习惯能用就行不管对象是不是官方推荐的。只要语法不错、激活能过怎么都能跑。ABAP Cloud完全不是这个玩法。它背后的核心理念是“SAP保证稳定的API契约”。这套体系把系统里的对象分成三六九等用release contract去约束C1等级的对象SAP把它作为公共API面向云客户发布接口稳定升级兼容有保障C2是面向认证伙伴的使用范围更宽C3基本是SAP内部专用云环境里想用语法检查直接不让你过。还有一批对象虽然还存在但被明确标记成Deprecated已弃用SAP的意思很清楚你新写的代码别再来碰我老的东西。打个比方。这跟城市里开专用车道一样传统ABAP是在八九十年代的普通马路上跑旁边随时有private road能钻就钻没人管ABAP Cloud是上了高架路不是你想开什么车型就能上Released API 就是你的车型许可Deprecated Object 就是那些已经被淘汰、但还没拖走的旧路障。你把车开上去先过的是收费站不是你的目的地。1.2 不是所有旧对象都叫 Deprecated也不是所有新写法都算 Released这里有个常见的混淆。很多刚接触ABAP Cloud的开发以为老写法等于DeprecatedSAP类等于Released。实际上没那么简单。系统里有大量对象既没有被标记Deprecated也没被列入Released API它们只是“没公开契约、不承诺稳定”的内部实现。这种对象在本地S/4HANA的扩展开发里可能还能调但过了ATC的ABAP Cloud规则就被拦下来。反过来一些名字看起来很“老”的API因为SAP觉得它仍然有价值也被逐步放入release state。拿最典型的cl_abap_context_info来说它把系统日期、时间、当前用户、客户端等信息统一收起来了相比老代码里直接读SY-DATUM、SY-UZEIT、SY-UNAME这类字段get_system_time这些方法就是公开API不仅有明确的契约在SAP S/4HANA Cloud这种没有传统系统账号概念的环境下也照样工作。我见过太多老开发守着老字段不放本能地拒绝换新API结果代码在本地顺利激活一传到云又被无限期卡住。所以推荐的做法不是按“新旧”判断而是按“API契约是否有文档化的release state”判断。下面这张表是我在自己项目里概括的不一定覆盖所有角落但方向基本不会错状态含义在ABAP Cloud开发模式中实例Released API有公开发布契约升级兼容有保障正常使用检查通过CDS视图、RAP类、cl_abap_context_infoNot Released / InternalSAP内部实现不承诺兼容语法检查通常报错大量CL_开头的内部类、部分Function ModuleDeprecated Object已宣布弃用仅存量兼容报错或强烈警告不建议新代码使用WRITE、CALL SCREEN、旧式ALV控件类1.3 模糊状态带来的代价编译失败、升级翻车、合规赤字有的开发觉得我代码只要能激活管它是不是Released API这里我要给一个比较现实的提醒编译失败只不过是最轻的代价。我遇到过真实场景。项目从S/4HANA 2020迁移到2022版本本地老系统里有段增强逻辑调了一个没有被release的内部方法。当时在旧版本里语法检查根本没拦云就绪检查也没跑结果升级后SAP在内部重构时改了方法实现重编译直接报错联调阶段才发现是API契约踩线。像这种问题如果出现在生产包的增强里回滚成本会很高。这就是Released API的意义它不是多此一举而是SAP给开发者的兼容性保险。Deprecated Object的麻烦也是类似的道理——你的代码引用的对象状态越边缘将来升级的路径就越不可预期。更不用说很多企业有严格的合规审计代码里一旦被查出大量Deprecated引用上到架构评审下到开发规范都过不了关。2. ADT 里快速鉴定 Released API 的几种实用打法说了一堆概念现在来点能直接上手的东西。2.1 最省事的办法F2 元素信息里看 Release State在ADT的ABAP编辑器里写代码光标放在类名、方法名或某个全局对象名上按F2会弹出ABAP Element Info窗口。在这个窗口的Attributes区域你能看到一行Release State信息写着类似“Released for public use”或“Not released”。我举个日常用得最多的例子。老代码里拿当前时间很多人直接写sy-uzeit。换成ABAP Cloud风格我一般用DATA(lv_time) cl_abap_context_infoget_system_time( ).把光标放到get_system_time方法上按F2Element Info里能清楚看到这个方法是released状态。这说明可以放心在ABAP Cloud代码里用。遇到有些内部方法Element Info里就是一片空白或者只有技术名称没有契约状态这时候就要警惕了等会儿继续讲怎么验证。这个方法的最大好处是快。你在写代码的过程中顺手按个F2就有答案不需要开额外工具。坏处是它只对单个对象做“点查验”你不能靠它把整个项目的合规性一次性跑完那种任务要交给ATC。2.2 Outline 视图里的一次“扫全类”看方法名有没有删除线如果你想一次性看某个类里哪些方法是Released、哪些被DeprecatedF2就不够用了。这时候要把Outline视图拉开Window Show View Outline。在Outline里展开一个类选中任意方法右下角的Properties视图会显示这个方法的Release State比如C1: Released for public use。更直观的是当前版本ADT的Outline视图对已弃用成员会用删除线样式显示。你打开一些老类能明显看到某些方法名上拉着一条删除线心里立刻就有数了这方法要么有替代要么已经不建议新代码使用。我自己的习惯接手一个不熟悉的SAP类之前先花二十秒把Outline拉起来过一遍凡是带删除线的方法就算能调也不作为首选。这个方法对浏览方法特别多的工具类非常实用比一个个F2按过去高效得多。2.3 把语法检查当成“云API契约的实时门卫”大多数从SE80转过来的人习惯是写完一整段代码再激活看哪里红。但在ADT里如果思路切到ABAP Cloud语法检查其实从输入那一刻起就在帮你验证API契约。注意一个问题很多涉及API契约的检查消息不会把红叉画在代码行旁边。你打开Problems视图会发现里面躺着好几条Error或Warning但编辑器本身看起来干干净净。这句话我要强调一下因为这个特性坑过不少人。建议路径Window Show View Problems然后把Problems视图固定到编辑器下方。比如你写了CALL SCREEN 0100.或者WRITE Hello.在传统ABAP的语法检查里这些可能只是warning但在ABAP Cloud相关的检查变体下Problems视图里会给你错误级的消息大意是“Classic Dynpro not supported”或者“Obsolete statement WRITE not allowed”这类。老开发常犯的错误就是只盯着编辑器行号看红叉不看Problems结果一直找不到编译不过的原因。2.4 用 Where-Used 和全局搜索反向“扫雷”这个技巧在迁移老代码时特别有用。比如团队决定把某条老BAPI调用改成新API你想知道这里全项目还有没有其他地方也调了这个老FM直接在编辑器里选中那个FM名按CtrlShiftGWhere Used List就能列出所有引用点。然后将引用逐一过一遍把已经确认有released替代的老调用列成一张待改清单分给不同的人处理比大家各自闷头乱找靠谱得多。还有更粗放但能快速定位的模式搜索CtrlH打开Search在ABAP文本里搜“CALL FUNCTION”、搜“WRITE ”、搜“CL_GUI_”能把传统代码里最典型的老写法定点搜出来。不过要提醒一句ADT的全局文本搜索在大项目里比较慢而且只能搜纯文本模式搜出来的结果还需要人肉二次确认。真正要做全量合规扫描请直接跳到后面ATC那段。3. Deprecated Object 的雷区清单与ADT定位技巧Released API搞清楚之后另一层就是怎么跟Deprecated Object斗智斗勇。3.1 十个常见雷区踩中哪个都不冤我把项目里看得最多的Deprecated/不推荐用法整理成一个清单每个后头附一句替代思路WRITE 列表输出老报表三件套在云开发里已不被认可。输出请走UI实在要演示就返回字符串别再用WRITE刷屏幕。CALL SCREEN / SET PF-STATUS / SET TITLEBARDynpro技术栈整体退出ABAP Cloud替代是RAP Fiori Elements。逻辑数据库GET 事件现在用CDS视图加查询逻辑更清晰。CALL FUNCTION 全系列部分老FM还在released列表里但大多数没有契约。替代方案是把FM封装成类方法尤其在RAP里直接调用FM通常不是好主意。老款ALV控件CL_GUI_ALV_GRID、CL_GUI_DOCKING_CONTAINER这些类在传统ALV年代很常见但在ABAP Cloud的UI场景已经让位给Fiori Elements和RAP。直接读取SAP标准业务表MARA、VBAK这类表在ABAP Cloud的很多场景不能直接SELECT必须走CDS视图或RAP的读取方法。Native SQL / 动态SQL拼接ABAP Cloud对直接操作的数据源有限制建议全部换成ABAP SQL或CDS查询。老式内部表写法不声明TYPE、靠表头行属于历史遗留写法新代码不要再用。REPORT 程序本身在ABAP Cloud环境下新的开发对象应该以类、接口、CDS、RAP行为对象为主REPORT这种可执行程序类型在云端开发中基本没有生存空间。带deprecated注解标记的类在Outline里显示删除线试用前先查替代类。这份清单看起来很长但你仔细看会发现大多数被点名的东西都有一个共同特点——它们是某个旧技术栈的入口。换句话说SAP真正想让你放弃的不是某一个语句而是背后那套传统的UI交互和数据处理模式。3.2 动态编程和白名单最坑的是“绕了一下”的引用第1章里说过还有一类对象不算Deprecated也不是Released API。最典型的是动态编程老代码里用一个字符串变量动态指定数据库表名或者动态生成一段ABAP代码然后运行。这种写法能骗过静态语法检查运行时才炸。在ABAP Cloud环境里这种方式基本上已被堵死。ADT的语法检查器对动态指定数据库表非常敏感你可以试试CONSTANTS: c_tabname TYPE tabname VALUE MARA. SELECT SINGLE * FROM (c_tabname) INTO DATA(ls_data).ABAP Cloud开发模式下这行代码很可能会被ATC与语法检查双重拦截因为动态表名无法在编译期确认它是否允许访问。这不是“Deprecated Object”的标签问题而是API契约的“静态可验证”特性被破坏了。所以我强调“Deprecated”和“Not Released”其实是两座山Deprecated是SAP说你最好别用Not Released是“我根本没承诺你用了自担风险”。迁移老代码时两类都要查。提示判断一个对象是不是Not Released最直接的方式就是看F2和Outline如果没有任何release state说明而它又是SAP的系统类默认按“没有契约占位”处理。不要赌它后面版本不会变。3.3 一次典型报错的排查链路从“表不可访问”到发现动态SQL之前我处理过一个真实改造案例。同事把一个老程序切到ABAP Cloud开发模式后ATC报了一条错误大意是访问数据库表MARA不受许可。一开始我们都以为是老代码直接SELECT了标准业务表按照规范把SELECT改到CDS视图就能解决。结果改完再跑ATC还是报同样的错。这时候我打开那段代码仔细看才发现问题不在FROM子句而在FROM后面的表名是用变量拼出来的DATA(lv_tabname) MARA. SELECT SINGLE * FROM (lv_tabname) INTO DATA(ls_data).ATC的报错信息指向MARA但根因是动态表名。因为检查器没法在编译期验证这个动态变量到底会指向哪张表所以在ABAP Cloud模式下直接判为不可访问。同包另一个类里用静态SELECT * FROM mara之所以能过是因为它已经改成走CDS视图读取语法检查器能看到确切的CDS对象。最后的修复方案是把动态表名的分支用显式CASE拆开每种业务场景对应固定的CDS视图再用静态SELECT去读。改造完ATC错误立刻清零。这个案例给我的启发是排查ABAP Cloud兼容性报错时不要只看错误消息指的那个表或那个对象要顺着代码的“间接层”往上追——动态编程、宏、隐式类型转换这些才是藏雷的重灾区。3.4 全局点名Deprecated引用的两种方式文本搜索毕竟粗糙。想在项目里准确找出Deprecated引用我的标准流程是第一先在Outline中看当前文件的成员状态用鼠标在类成员间移动留意删除线。适合单文件自查。第二对整个传输请求或整包运行ATC用ABAP Cloud Development的检查变体把结果精确列出。这一步是真正的“点名”它会把代码里的非Released API、Deprecated语句、不合规的表访问全部列成明细每条都有对象名、行号和官方说明。到这一步文本搜索只能算辅助手段ATC才是真正能让你放心交付的工具。4. 从传统ABAP代码到ABAP Cloud一段最典型的改造实录理论说得再多不如看一次实操。4.1 病症老代码长什么样为了讲清楚我虚构一段非常典型的传统写法纯演示用不要拿它跑生产REPORT zbb_demo_old. DATA: lv_matnr TYPE mara-matnr, lv_text TYPE string. SELECT SINGLE matnr INTO lv_matnr FROM mara WHERE matnr 100-100. IF sy-subrc 0. lv_text |Material found: { lv_matnr }|. WRITE: / lv_text. ENDIF.这段代码放在传统系统里没有任何衍生问题但在ABAP Cloud模式下它碰了至少四类雷新建REPORT对象在ABAP Cloud开发中不受支持直接SELECT标准表MARA属于直接访问SAP业务表WRITE是弃用语句列表输出在Fiori时代没有任何画面整体结构没有封装性逻辑裸放在可执行程序里不利于RAP和后续测试。4.2 换血把数据访问收进CDS把逻辑收进类第一步数据访问不能直接吃标准表。建立一个CDS视图把这个业务需要的材料主数据字段包进去AccessControl.authorizationCheck: #NOT_REQUIRED EndUserText.label: Material header with text define view entity ZR_MATERIAL_TEXT as select from mara left outer join makt on makt~matnr mara~matnr { key mara.matnr, makt.maktx as material_name }第二步把逻辑封装成一个类方法不再放REPORT里CLASS zcl_material_service DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. METHODS get_material_name IMPORTING iv_matnr TYPE matnr RETURNING VALUE(rv_name) TYPE makt-maktx. ENDCLASS. CLASS zcl_material_service IMPLEMENTATION. METHOD get_material_name. SELECT SINGLE material_name FROM zr_material_text INTO rv_name WHERE matnr iv_matnr. ENDMETHOD. ENDCLASS.第三步输出层不再用WRITE。方法返回rv_name由调用方——可以是RAP行为实现、可以是Fiori后端Action、也可以是别的服务类——把这个字符串渲染到界面。这样就绕开了所有老式屏幕语句。这一步的取舍逻辑值得说一句我为什么坚持第一步先建CDS视图因为ABAP Cloud里大量新技术的入口都要求数据源是CDS实体RAP的查询视图、行为定义的事务数据处理、甚至是后续想接入Fiori Elements做列表报表全都以CDS为地基。与其后面一次次回头补视图不如一开始就把数据访问层切干净。同理业务逻辑封装成类是因为RAP行为实现和增强框架都面向类方法一个REPORT程序没法被RAP直接调用。4.3 ATC怎么跑跑了结果怎么看这一节专门讲操作路径因为太重要了。在ADT里用项目资源管理器选中最顶层的项目不是某个包右键 - Run As - ABAP Test Cockpit。弹窗里可以选检查变体。如果你团队里没有专门配置过ABAP Cloud的变体至少在变体下拉里选一个包含“ABAP Cloud”规则的变体。跑完之后ATC结果视图会列出每一条问题分类是Error、Warning、Information。用ABAP Cloud开发模式的内置变体跑你很快会看到形如这样的消息不同版本版本措辞略有差异“Database table MARA is not released for direct access in ABAP Cloud”“Obsolete statement WRITE is not allowed”“Reports and Dynpros are not supported for ABAP Cloud development”这时候对每一条消息右键通常能看到官方解释链接和对象位置。我的建议是不要只看ErrorWarning信息也不要放过。Deprecated的引用在ATC里经常是Warning但积累多了后续升级就是一堆不确定因素。实际项目里我会让ATC结果有一个固定的“基线”要么0条错误要么团队认可的一小撮等待业务决策的Warning。每次提交代码前跑一次如果错误数比上次多了先在内部例会说明原因。这套流程不复杂关键是坚持。4.4 提交前的自检清单15分钟换一个不被挑战的包每次提交前我给自己设了一个15分钟的检查流程共享给团队后大家都这么干当前代码在Problems视图里有0条Error。能激活不代表没问题先看这里。涉及SAP系统类的调用F2看release state不确定的单独查。用ATC的ABAP Cloud变体跑过当前包错误为0如果有Warning逐个确认理由。没有新触达SAP标准业务表查询全部经由CDS视图或RAP读取方法。编辑器里没有WRITE、ULINE、SKIP、CALL SCREEN这类老语句。新建对象类型是类、接口、CDS、RAP而不是REPORT、FUNCTION GROUP、TRANSACTION。业务方法没有动态表拼接、动态运行这类绕过静态检查的暗门。在Outline里检查被调用的SAP方法没有删除线标记。这八条看着细但执行起来也就是几分钟的事。真正养成习惯后ATC报错率会直线下降代码Review也会快很多。5. 沿用ABAP Cloud模式之后我的日常习惯和个人体会到了这一章不写清单了聊几句真实的体感。5.1 遇到拿不准的API我按这个顺序验证拿不准是常态不用慌。我个人的决策阶梯是如果知道类名先F2看release state顺手如果是要批量排查老代码跳过F2直接ATC如果ATC报了错但没给替代对象去SAP API Hub或者ADT的帮助中心搜关键字如果还没有答案以“[对象名] ABAP Cloud deprecated”为关键词搜社区通常能翻到前人的处理结论。一个真实感受这套流程大概跑了半年之后我连F2都很少按了。不是因为记住了所有API而是养成了一种“契约敏感度”——看到某个对象第一反应是先判断它属于哪个抽象层是UI层、数据层、还是业务逻辑层如果是UI层的老ALV直接PASS如果是数据层的表先想CDS如果是业务逻辑类再查release state。这个思维习惯比任何工具都重要。5.2 团队协作不要在口头规范里谈API把它落到工具上口头说“大家尽量用Released API”等于没说。我们团队后来做了两件事一是把常用的Released API和替代老API的对照表放到了Wiki任何人写新代码前先翻一眼二是把ATC检查直接配置成保存时自动弹出问题列表谁也别想“假装没看见”。这种做法不依赖个人的自觉而是靠工具的恒压效果显著。对了还有一个小技巧ATC结果支持导出。每次迭代结束我把ATC导出的Excel作为交付物的一部分发给测试和架构组他们能在没有ADT权限的情况下也看到哪些Warning是有意保留的哪些已经清零。这个习惯帮我避开了不少“项目验收时被翻旧账”的情况。5.3 把“找API”变成肌肉记忆最后分享一个私人习惯。每次看到一个老API我会强迫自己在内部笔记里记一个问题“它在ABAP Cloud里的替代是谁”哪怕这次不需要替代记下来下回遇到同类需求就不慌。比如我第一次整理WRITE替代时记录的是“输出走UI层返回字符串给调用方”第一次整理CALL SCREEN替代时记录的是“去理解RAP的基本架构”。几个月下来笔记里积累了满满一页“老API - 新思路”的对应关系相当于自己给自己做了一份定制版ABAP Cloud开发手册。这套“找替代API”的肌肉记忆才是ABAP Cloud开发真正的门道。工具会用思路也清楚剩下的无非是写代码的事——而写代码这件事恰恰从来都不是 ABAP 开发最难的部分。
返回列表