HCM P&F is composed of several “parts” that must all work well together, and when they don’t, finding the cause can be a tedious undertaking. For HCM P&F, we have Adobe Interactive forms, the portal, webdynpros, ABAP generic services, ISR framework, workflow, HCM P&F configuration, decoupled infotype configuration, and more all working together so at the end of the day it all appears so easy and trivial to the end user. “Hey look….that drop down list only shows the open positions I am responsible for as a manager…that’s pretty neat.” is about the extent of a “oooo ahhhh” response you will get from an end user as they have no idea how much was involved to make that “neat” drop down list work in the first place. But when that nice little drop down list isn’t working correctly, you will definitely get much more of a response. (haha)
Because of so many “moving parts” in HCM P&F, there are so many places where “bugs” can live and hide. This blog serves to give a introduction into some debugging tips, tricks and information that I have found useful in my experiences. I know what you’re thinking now….”Chris, you mean to say that you make mistakes and accidentally create bugs!?!?? *gasp*” (haha)…well, yes, sorry to say, my ego is not that big nor my talent/skill that extensive…I too can readily admit that I make mistakes….BUT…..I do know what to do to quickly find and correct them. That’s what I hope to share here.
First off, I want to discuss what this blog will not cover. I will not talk about issues related to the infrastructure itself. If Adobe credentials are missing? If the portal isn’t working? If the HCM P&F start application or edit form application isn’t coming up correctly? If the ADS service isn’t running? If permissions are missing? All of those are issues easily handled by your various administrators (BASIS, portal, etc), and the symptoms and/or error messages (blue screens) you see when these occur are very descriptive in identifying the underlying issue (ie. “ADS service not running”).
Second, I will not be getting into debugging workflow. Again, you should have a workflow admin who will be well acquainted with identifying and resolving workflow related issues. Here, I am speaking strictly about the flow, bindings, values, approver determination, etc. in workflow itself. The techniques I will discuss can be used in some the tasks that workflow will execute though (such as editing or approving a form after a process has started).
Third, the examples shown relate mainly to processes prior to EhP4. This will change slightly when debugging processes related to SAP_PD (new OM service), fast data entry and multi-object (mass entry) processes. However, the same underlying methodology should be applicable.
Fourth (and last…thankfully! haha), this will not cover security related issues. I am sure you have very capable security folks who are more than well versed in the various tracing tools and other resources at their disposal….and we don’t want to get on bad side of the security folks, do we? (haha)
With that said, let’s get started……….
The first thing we will need to do is set up our debugging environment. You can very easily test and debug from within the SAP GUI using the “test process” transaction. However, you will probably want to test your process as an end user would see it. Likewise, you will probably have more/different security than an end user would have. Lastly, you will likely need to test for various scenarios (ie. several test users). Therefore, setting up external debugging for a different userid than your own will be your best route.
Once you have your “external” debugging set up, you will make sure to set an “external” breakpoint in the code where you suspect errors are occuring or you want to pause operation to check values or whatever other reason. While having the SAP GUI up and running with your breakpoints set, you can then execute your process from the portal for your debugging user. This will trigger your “external” breakpoints correctly if they are “hit” during processing.
In order to make sure you have your debugging set up correctly, you can simply check/set this from our old favorite, transaction SE80. From the top menu item “Utilities”, select, “Settings…”.
Here, on the pop-up window on the ABAP Editor top tab and the associated Debugging sub-tab, make sure we have the correct user set for external debugging.
In the situation where you are testing/debugging for several test users, you will simply change the “Users” field value each time before executing your process. This makes it very easy to locate security, country specific, or other variations in user settings and configuration.
With our debugging environment all set and ready to go, let’s get into the really fun stuff.
DEBUGGING END-TO-END IN HCM P&F
In most every situation, you will find that the interaction between the user, the form and the backend follows are fairly simple path. This communication path is basically:
However for our purposes, the debugging path generally works as follows:
- Adobe form
- Our generic service
In other words, we will try to start with the easiest, most common locations of problems first and work backwards…or as some folks know it, the “K.I.S.S.” method. With that said, we start with the places where we can actually be the cause of the problem….the places we actually develop code/config.
Within the script you are looking at, you can simply place a script such as :
This will pop-up an alert that just says “here” whenever your event happens. You can also pop-up an alert showing the current value of your selected form field by adding in,
Be very sure to remove all of your debug pop-ups!
Generic Service methods and configuration
The next most common place for bugs to hide is within the generic services we develo. We can determine our BAdI by looking at the configuration for our process….
Then, we can pull up our BAdI implementation for our generic service in transaction SE19. The backend service “name” will match up to the “service Id” passed to the filter for our specific BAdI.
This is “how” the HCM P&F framework knows which implementation of the BAdI to call since it is really all the same BAdI.
For our own generic services, we have two main methods to check/debug (the other methods are really used/called by configuration in the Design Time when we pick the backend service):
In many cases, we do not use the initialization method. However, if we do, we use it to set default values for some fields on our form.
The important information to us here is: SERVICE_FIELD_VALUES.
This structure will contain the fields and their values that are available to us during initialization based on our configuration.
You will typically look for to see what or if your own operation of your own generic service is being called:
Here, we will be looking for two main things….
SERVICE_OPERATIONS – tells us what operation(s) we are trying to execute
SERVICE_DATASETS – tells us our field(s) and their value(s) for the operations)
If everything looks correct in our specific service or if we don’t see the values coming in correctly into our service. Then we must look at our HCM P&F configuration. The issue might be related to the order of our services. This is tricky and will come from experience more than anything, but there are a few things to be aware of.
1. The order of all of your services will be enforced during initialization. However, during the operations themselves, the SAP standard services will be called last. What you just read might not be immediately obvious. What I am saying is that if your config looks like:
During initialization, that order will be enforced. This is useful if for instance we want fields tied to SAP_PA to initialize so we can then use them later in our own services (like 2 and 3 shown). However, when it comes time for our operations to trigger, SAP will requeue this for us as:
Don’t ask me why SAP does this (you can put a breakpoint in the dispatcher class to see how it re-stacks the operations regardless of configuration). I think it is probably to protect us from ourselves and especially to insure that when SAP_PA “commits” a change that nothing else happens. If you attend any of SAP’s HCM P&F classes or some of their material, they will drone on about “always place the standard SAP services like SAP_PA, SAP_PT, or SAP_PD at the end of your configuration” so much so that I have had people that went through the training argue with me that I am “doing it wrong” without having any understanding or knowledge of WHY they were told to do this. Well, the above information is “why”, and you won’t be “doing it wrong” if you are aware of what is actually going on. However, just know that “odd” things can happen if you don’t keep this in mind.
2. “If one fails, they all fail”…remember that, commit it to memory, recall it when you think you have absolutely lost your mind debugging HCM P&F. What this means is that if any ONE of our generic services’ operations fails, they will all fail (ie. no data changed). I learned this the VERY hard and painful way. Using a watered down example, I had for instance:
In the first generic service, I checked the “effective date” and added one day to it. In the second, I simply provided the possible action reasons for a given action code. In the third, checked to make sure the position field was selected.
Now, the effective date would initialize correctly and the form would come up. Say the effective date showed as 09/22/09. I would change the date to 10/15/09, do whatever else and then select “check and send”. However, the form would come back and show the date as 09/22/09….not 10/16/09. WHAT?!?!? I debugged. My first service worked great…the date changed as it should…I could see it come in and go back out. So what was the problem?!?!!? I moved the debugging further. In SAP_PA, the date was there. In the second service, the date was there…so SAP_PA hadn’t changed it. Even in the fourth service, the date was correct…even though it wasn’t used in that service. HOWEVER, an error was occuring in the third service that was uncaught. It didn’t stop the process or throw any error…..it simply bombed out….which in turn bombed out all the previous service. All the data was returned to it’s initial state. Boy was that a “fun” one to discover. Lesson learned.
3. Beware of “User Events”. My “love” of User Events for HCM P&F is well documented (haha). However, here are two common issues for your services not behaving correctly due to User Events. First and foremost, make sure you select ALL the necessary fields to be part of your “event”. If there is any chance a field is needed in the operation you are trying to fire with your event as well as any other operations that might get called (again, my “issue” with user events), you must take great care to make sure they are included. Otherwise, their value will not be passed and in some (most?) cases, will be lost (blanked out) upon the execution of the event. Personally, I select just about all of the fields just to make sure and then I use other “tricks” to make sure only the operations I want called get called but that’s another story. Secondly, beware of “orphan” user event fields. I reported this as a bug in my blog about “Gotchas” back during EhP2, and it is still around. Basically, if you have a form field defined which is selected for a user event and you then delete that form field, it does NOT get removed from the user event….it exists as a “ghost orphan”, and you will get an error on your form when trying to trigger your event. To fix this, add the field back as a form field, unselect it form you event (it will magically reappear! haha) and then go back and delete the form field.
If we do not see what we are looking for….our operation not triggered, data incorrect, or we want to look at the next “higher” level…for instance to see all operations that are being called, their order and the data exchange, we look in the dispatcher class for HCM P&F.
From there, we work backwards. We can see what operations are being called by the dispatcher. The dispatcher is like our “engine” for HCM P&F and handles putting together what operations get called in what order and what fields and data go to them.
Our main methods of this class are highlighted in the following image:
We can set breakpoints in the method INITIALIZE and FSCN_INIT to see what is happening for our process during initialization.
We set breakpoints in FSCN_DO_OPERATION to see what is happening for our process during user events and/or “check and send” events.
You will also see that the “dispatcher” class will call “mapper” classes. There will be “mappers” for SAP_PA, SAP_PT, etc. as well as one for generic services. Another useful place to check (although not necessary) is class CL_HRASR00_GENSERV_MAPPER and the method VERIFY_DATASETS.
We can set breakpoints and compare loc_service_datasets_old to loc_service_datasets_new to see what data is sent in (old) and what data comes out (new) of every generic service called.
If we still do not see our operation being triggered/called (or any for that matter), we can check to see how the ISR framework is handling this communication.
This handles the communication between the form and the backend via the ISR Framework. Our main methods of interest are highlighted.
Method INIT_SERVICE_REQUEST_INIT will handle our form initialization.
Method SCENARIO_PROCESS_USER_COMMAND responds to events/commands coming from the form such as “check and send”, “return to author”, “save draft”, etc. This is very similar to your typical “user command” routine in dialog programming. This is particularly useful to test whether your form is really responding at all.
This transaction will become your new best friend with HCM P&F. You will be directed to transaction ST22 most often from errors with HCM P&F known as the “blue screen” errors. This can be caused by a wide variety of issues. You should read the message carefully and follow the course of action it suggests (in the section under the blue “box”).
Here is another example in which the ADS service is no longer runnning….
In ST22, we will locate our error (typically, the “blue screen” will give us the information to look up). The following shows a typical error I often run across with HCM P&F…
We double click the row to see the actual error log for the item. From this, we are interested in a key area:
This tells us where the problem occurred. Then we can see where in the source code itself as well:
We can click “into” the source code and actually set a breakpoint to test this code and see what is occurring. Based on experience however for this example, I can tell you that this relates to the “structure” of data coming INTO our generic service operation not matching the structure coming OUT. This usually means we added a field in the service’s operation that the interface was not prepared for. We can set breakpoints to read and compare:
They should match in the fields passed. They do not necessarily have to match in the NUMBER of the same field passed. So I could pass over one field called NEW_ANSAL with fieldindex 0. However, I might get back NEW_ANSAL fieldindex 0, NEW_ANSAL fieldindex 1, and NEW_ANSAL fieldindex 2. However, the above error would occur if we did NOT pass over NEW_ANSAL but we had NEW_ANSAL fieldindex 0 sent back to us. We must makes sure in the HCM P&F config that we are passing over the same structure of fields that will be coming back.
In general, you can use ST22 to find the “problem” code and then debug from there. I hate to say it, but the location given as the source of the problem is often incorrect. It will happen to be whatever code location actually finally caught the error. You will most likely have to dig deeper down to find the real issue.
Well, that covers the basics for debugging HCM P&F….again, the basics. Past this, you can delve further into more advanced methods and topics (such as inspecting HCM config that affects us, decoupled infotype configurations and classes, advanced HCM P&F config, etc). I wanted this to serve merely to get your feet wet…..and I can’t be giving away all my tricks!(haha) As always, I hope this helps. Have fun with HCM P&F….I sure am!!! Till next time…