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.