Hello, SAP, Where Are My Global Classes?
Recently, in a routine code review, I had to disappoint a teammate by pointing out that the standard class he was so excited to find should not really be used.
The class in question was CF_RECA_MESSAGE_LIST and it was meant to add messages to the application log. What’s wrong with this class, you ask? Well, for starters it belongs to the package RE_CA_BC. Our application has nothing to do with the real estate. In ECC to S/4HANA migrations, the customers have already been burned by milk of using the objects from random packages and industry solutions that SAP “reimagined as not existing going forward”. Therefore, now we are blowing on water and staying clear of such dependencies.
The global classes do not have a “released” indicator and other than checking the SAP Notes, there isn’t a way for anyone to know if a class is supposed to be used in the customer applications or not. Of course, the “not released” indicator in FMs never stopped anyone from using them anyway. But that’s exactly the type of mistake we all should be trying to avoid, no?
The question is: how?
One thousand two hundred sixty-nine classes on the wall
In some previous projects, I used ABAP Logger, which is very helpful. But not every customer is open to conversations about the open-source code, and we need to find something more standard.
Application log creation is performed by the FM BAL_LOG_CREATE. (Isn’t it funny how everything still ends in some function module?) The first light-bulb moment was to run “where-used” list for the FM and see in which classes it’s used. The result? 1269 global classes.
You would think that maybe after the first 200 someone would stop and think “hm, surely I’m not the first person to need this, so let me search if there is a class for that already”. But then again, maybe everyone is facing the same dilemma of potentially adding a dangerous dependency?
My second light-bulb moment was to check in the same package where the FM itself sits. This was effort yielded classes aptly named CL_BAL_LOGGER and CL_BAL_LOGGING. These classes don’t have any documentation (they never do, I don’t even check anymore) and no indication whether they are OK to use or not. But at least being in the same package as the FM itself, they have that warm and fuzzy feel.
Functionality-wise these classes are not great and don’t offer a convenient method that would take some BAPIRET2 table and just add all the messages to the log. No worries though, we are ABAPers and we can create a wrapper to do whatever we need. Class number 1270, here we come.
Dude, where is my class?
This post is not about the application log functionality. You could take the story above, replace application log with literally anything (like Excel upload, wink, wink) and it would have the same plot.
It was the same story before with the function modules. Need to update or upload something in SAP? Off you go, to Google and to SAP Community. Keep fingers crossed that someone has already shared what you need. Otherwise, you’re facing a trip down the debugger path into the dungeons of SAP standard code.
It has gotten better with the web APIs that can be found on the API Hub, providing they exist. (Which is the whole different story.) But when you need a class today, in an on-premise system, how do you find it?
Another thing we needed recently was to create the pricing condition records in SD. In the old days, there was pretty much no functionality for this. There was shady BAPI and even worse FMs. I’ve seen many companies resort to BDC and can’t blame them. Well, turns out SAP finally created an API class called CL_PRCG_CNDNRECORD_API_FACTORY (it exists in S/4HANA 2020 system, at minimum). How do I know this? No, not from “ABAPer Weekly” magazine or some such. I found it on Google because one person was kind enough to post about it on SAP Community. There is no way I would’ve found it otherwise.
And legacy code is so much fun. In the fragment I was supposed to copy-paste from an old program to a custom class, the unreleased FM CONVERT_STREAM_TO_ITF_TEXT seemed like not the best solution. Converting a string into a TLINE table is a common task, surely there is a class for that in 2022. Let me search. CL*CONV*ST*? Nope. CL*STRING*… CL*TAB*? Nope. CL_ABAP_STRING_UTILITIES? Nope. I’m beginning to feel like a detective who is desperately shaking the dying victim’s body at the crime scene, screaming “THE NAME!!! GIVE ME THE NAME!!!”
I have a BDC and I’m not afraid to use it
Look, SAP, you have literally thousands of customers running the on-premise systems. And they will continue doing that for much longer than you think. The way to achieve most business functionality in those systems is still to use a BAPI or a global class. BTP services are not very helpful here, let’s just be real. So, if you want ABAP developers to do our job well, the time to start sharing information with us more generously and clearly is right now. After all, we’ve been asking since 2014.
I'm sorry that it will mostly be italians getting the reference but... here are my 92 minutes of applause 😉
Wink wink for Excel also appreciated, I see that for the text conversion I recentrly wrote my own method because I couldn't find any.
Yes, indeed, SAP should get real and provide an official API list for older releases which are still supported: to the PHBs it won't make any difference but the cursing and hissing going on among developers should noticeably decrease 🙂
Thank you! TIL another cultural reference. 🙂
"Wrote my own method because I couldn't find any" is so true. And then you suddenly stumble upon an SAP class that does exactly what you need.
That's actually another good reason for following the forum closely: you learn a lot just by reading the answers to interesting questions.
Here's the cultural background 🙂
Yeap, at least for new stuff like released Steampunk, that would be nice.
Question A in https://blogs.sap.com/2020/12/11/my-open-questions-from-sap-teched-2020/ raises the same concern
Well, SAP did not provide it so, https://blogs.sap.com/2022/01/03/steampunk-released-abap-api-first-draft-is-up/
For the scenario of using something new, in abapGit we have CI helping, if usage of a SAP standard object is introduced, it is added as information to the code review(PR), example: https://github.com/abapGit/abapGit/runs/6223709489
Oh, and when we find a unwanted type, add it to https://github.com/abapGit/abapGit/blob/main/abaplint.json#L134 so everyone will get errors if trying to use it
Thank you for these additional references! I missed your 2022 blog because it had Steampunk in the title and it's not something I care about at this time. 🙂
No one could possibly ask anything more from you as you've been pretty much the driving force behind many ABAP development improvements. There should be a shrine or a statue or a bust, at minimum, for you at the SAP HQ. 🙂
It is great that community steps in to fill in the void SAP doesn't fill. It would be great though if SAP put some effort in it too, with all the budget and a burgeoning team of "developer advocates".
But considering that nothing changed since Christian's blog in 2014, yours since 2020, and many others, there isn't much hope. And it's a pity.
Thank you for all you do!
Some info about whether the class is "released" or not might be its' Package interfaces (in which it is included), but this isn't an "official" one.
Excellent blog, Jelena! Some ask "Why is adoption of object-oriented coding practices" so slow in SAP? Well, in my view, the lack of a well-designed general OO base library is a main reason. BTW, designing such a library is complicated by the fact ABAP doesn't support a modern namespace concept and the limitation of 30-character names of which 3 (or 8!, CL_ABAP_) are already taken by prefixes. Still love ABAP though!
We do have packages and subpackages though. Could be relatively simple for SAP to say at least hey, stuff in package X is safe choice but stay clear of package Y.
But I guess an API library is not something you can sell. Or brag about in the keynote. Even though this would make tremendous difference in the life of thousands of ABAP developers. And would make many things easier for the customers as well. The question is: does anyone at SAP care enough about this to take action? I guess we'll see.
A standard library in JS would be nice to have 😉
something like https://github.com/open-abap/open-abap ?
the method is implemented via dark JS magic
No, not really: I was referring to the fact that JS historically does not have ONE standard library, unlike C.
Extremely intriguing , great job and a debt of gratitude is in order for sharing a decent article.
Wish SAP had embarked in the early 2000s on a ".NET" type of project. Microsoft's .NET base library is pretty nice and harmonious. I've copied some of their naming in my own classes like ZCL_FILE, ZCL_DIRECTORY, ZCL_STRING, ZCL_MAIL_MESSAGE, ... What the heck, maybe Microsoft should just buy SAP!
There is the XCO library, https://help.sap.com/docs/BTP/65de2977205c403bbc107264b8eccf4b/c154dffe892b4d9ea4566722f0bcd5f1.html
but well, its, well, hmm, no comments
You have already described the steps to finding the "best" API, and pretty much how I go about it. Do a where-used, look at the packages, try to find something 'core' rather than some obscure fringe module.
SAP does have package interfaces - only exposing that which you want the outside world to use and keeping all other classes private. This is a form of 'release flag', but the downside is that enabling package checks is such a big shift and needs so much correction that I don't know of any customer who has actually switched them on or uses them.
and package assignments are typically just "something I have to do because SAP asks", so there's not a lot of thought put into this.
Yeah, I do notice a trend over the years customers have moved from ZDEV or Z000 or Z<CompanyNameAcronym> with 26000 objects in it to a more fine-grained ZDEV_MM and ZDEV_SD
It's a shame packages tend to be under-utilised, in my experience organisations tend to rely on namespaces instead and encode a whole bunch of stuff into redundant or unreadable naming conventions. The ones that really get my goat are when they insist on putting "CL" in the middle of a class name, a la ZMM_A_CL_PRJ_NS_descriptivepart.
That one just takes the cake. Consultants work with dozens of clients. If 99 clients just go with ZCL... and suddenly client 100 is no, use ZSD...CL...whatever, guess what happens at client 100? Everyone just gets confused, makes mistakes and then there are silly transports just to rename something for the sake of... what?
Anecdotal evidence is not necessarily statistically accurate, but I've seen it more than once on way under 100 implementations 🙁
In one case the dev guidelines even stated exception classes must follow "Z..._CX_...<name>", even though <7.5x will insist on ZCX/YCX.... The author(s) obviously never created any themselves...
The fact that I read this comment and thought "oh yeah, I remember reading something about package interfaces" tells you everything about how popular these are with the customers.
...and how convenient to look up, don't forget that