Dealing with downward and cross-system compatibility
Now the holiday season is over (at least, for me 😥 ) it’s high time to write a new blog post. So here goes….
Just recently I have been working on a few ABAP tools that are now being used on several types and releases of SAP systems. I don’t want to go into the details of these tools, but I want to share some experiences with you regarding downward and cross-system compatibility. I hope that I can give some tips so you can prevent the types of issues that I ran into during testing and deployment of these tools.
What did happen?
The above-mentioned ABAP programs were aimed at ECC and NON-ECC systems and beforehand it was decided that ECC50 should be part of the scope. You should also know that most of these tools were installed using transport requests (the more serious stuff J) while a few others were installed using a simple upload procedure. The transported tools were created in specific SAP Namespaces, requested for this purpose.
The SAP-system that we use for these types of developments is an ECC6 system, recently upgraded to enhancement pack 6. This means that is runs on a WAS731.
Beforehand, we were aware of differences between ABAP in WAS640 and WAS731, especially regarding method chaining and string templates. So of course we decided to be very careful not to use these new powerful options. An automatic downward compatibility check doesn’t exist in the Code Inspector, so we had to rely on alertness, enough black coffee, and peer reviews. Especially the latter has helped us tremendously in detecting possible issues.
But whatever we did to prevent issues, we still ran into problems when importing the transport requests into other systems. Happily, our company also has a few other SAP systems that we are allowed to use to verify technical quality and tool functionality, so in the end we were able to test and adapt the tools in such a way that we only ran into problems on our own SAP systems. For these tests we used a basic WAS702 system, an ECC60 system based on enhancement pack 1 (WAS700), and an ECC50 system (WAS640). We actually tried if we could install one tool on an R/3-Enterprise system (WAS620), but there we ran into too many technical and functional issues. Think ‘CL_SALV_TABLE’ and I’ll say no more. Recently, our ECC50 system has been upgraded, so this limits our development options a bit. Product are now only developed on WAS700-basis, but tools can still be useful in older versions.
There are two things that were obvious to us before we started any development.
First of all, if you want to be downward compatible, don’t use any of the new ABAP-options that were introduced in WAS702! (This is were you say: ‘Duh..’). Actually, this is a quite a list, so you have to focus on the big stuff: expressions, chaining, string templates.
Second, if you reuse SAP workbench objects in your code, you must check if the interface (or signature if you like) has been changed between SAP versions. It can even be the case that a class, method, table, data element, or function module doesn’t exist yet in older versions. For upward compatibility, you can rely on released SAP function modules, but this status doesn’t exist for classes or any other workbench object. The best you can hope for is that SAP adheres to the “Open/Closed Principle” that states that
software modules should be open to extension, but closed for modification
In fact, although it’s an obvious thing to take into account, I can still remember the first time I uploaded a simple ABAP tool in an older SAP release and ran into a runtime error: in the newer WAS-version, an obligatory import parameter had been added to a SAP function that wasn’t there in the previous release.
Less obvious stuff – downward compatibility
One less obvious issue that we ran into when installing the tools on older ECC systems is related to type-pools (or is it type-groups, or type-pool? That’s a bit confusing, but that’s another story…). We could have prevented this issue if we had remembered all of the changes between WAS700 and WAS702. But we forgot that, as of release WAS702, you don’t have to declare type-groups in your source code, class or interface definition anymore. They are just ‘there’, whenever you refer to their types or constants. You have one guess which type-group we forgot to specify in several locations. (“you say ABAP, I say EBEP, let’s call the whole thing of”).
In one product that we developed, we implemented ABAP-unit tests in almost all of our public methods. However, not only the syntax of the test class definition but also the location of unit test code has been changed as of release was702. Actually, it was a hell of a job to solve this problem, but it helped tremendously that we created the actual Unit Tests in separate global classes, using inheritance to link them to the local unit test classes (thanks, René van Mil). We now only had to delete these local test classes in our delivery system, which is a separate SAP system based on release WAS702. (“Nice work if you can get it”)
And there is even more – cross-system compatibility
And then the import of the transport request into a CRM-system failed big time. What happened was that we used some references to standard SAP data elements and type groups that didn’t exist on an CRM-system or any other type of SAP system. We had anticipated that a data type like ‘VBELN_VA’ only exists on ECC-type of systems, but not that other less functional related definitions, for example a range table for development class, didn’t exist on all SAP-systems.
And here are the tips…
I assume that this list is not complete, so please feel free to add other tips in your comments.
- If possible, develop products on a SAP system that is based on the lowest release that you are going to support;
- If you are developing a tool that is going to be used on different types of SAP-systems (ecc, bi, crm etc), use a basic Web Application Server for this. Every workbench object that exists on such a system will also exist on any other type of SAP-system;
- Don’t rely too much on SAP dictionary definitions. For product development, I choose to define my own domains, data element and table types. This way compatibility across releases and systems is assured.
- Sometimes, there is no other option than to create release-specific versions of your code. If a function or class has been replaced, this is probably the only way to go.
- Use polymorphism to decouple release-specific classes from your main product. In the days of R/3 3.1, I already did something like that using dynamic function calls with a fixed interface.
- If a new parameter has been added to a function module, you can also insert two almost identical call function statements: one with and one without the parameter. By checking table FUPAREF you can determine which function call should be executed.
- Search for functions with status ‘RELEASED’ and skip functions with status ‘OBSOLETE’. I know that several functions that you need are not released at all, but who knows, sometimes you just might get lucky.