Auto generating UML diagrams from ABAP code
Alternative title – I hate doco
It’s kinda a mantra that I live a reasonable part of my life to. I think the above image is a not unjustifiable representation of my feelings about documentation:
But there are many good reasons that I should be doing doco. Most of them are supposed to save the customer money in the long run. And occasionally by doing the doco, I even find some small errors in my code that I hadn’t seen before.
InnoJam Sydney 2011
Before InnoJam had any of that fun fluffy design thinking aspect to it, we ran one in Sydney. It was good fun, and people could build whatever the heck they wanted.
In staying true to my aversion for writing doco, I came up with an idea about auto-generation UML diagrams from SAP code.
Here’s a video of the solution we came up with:
here’s a link to the Prezi that I presented in that video:
I wrote a blog post about it:
“Programmers are lazy” – InnoJam them!
But it was long time ago and the move to a new version of SCN has kinda buggered it up.
Anyway, in short – Rui Nogueira never managed to get the terms and conditions of CodeExchange changed to a level where I’m happy to support it and put code in there. I’m pretty sure he tried though. So I didn’t do anything with the code.
Fast forward 3 years
I have a whiteboard in the office covered in post-it notes. They all represent at least one development that I’ve done for the current project I’m working on. At the beginning of the project, I was very good, and did all my doco as I went along. Then the poo hit the fan, and everyone wanted everything done yesterday, and didn’t care about doco.
So I now have a whiteboard full of post-it notes that represent potentially weeks of doco hell for me. So in my “free time” in the evening I decided to see if I could recreate the solution that we’d built in Sydney, and perhaps make it a little nicer.
The first thing I decided, was that I was NOT going to try to build the graphical output myself. Having had lots of fun in Sydney trying to make Gravity do something it really wasn’t designed for I thought I’d research how else I could get my interaction diagrams created.
If in doubt Wikipedia
There were loads there, and I’d pretty much decided on UMLet when I discovered something about interaction diagrams. Basically, interaction diagrams are supposed to show interaction between objects. Bit bloody obvious really. However, the thing is, if I’m documenting my code, I’d really like to show the interaction within my objects too. I.e. if I make a call to a private method of my class, I’d really like that to show up in my diagram. Given that interaction diagrams are only supposed to show external interaction it’s not surprising that most of the tools for creating the diagrams don’t really support this idea of internal object calls.
So a bit of browsing later and I found PlantUML. It has some awesome functionality for creating sequence diagrams, actually, most UML diagrams it seems, but it was the sequence diagrams that I was interested in.
Here’s a simple example:
See how it’s quite possible to show “internal” calls of an instance and also show the life time of those calls. This feature I didn’t find on the other free UML tools that I looked at. There are a bunch of other formatting features that can be used too. If you’re interested check out their website: http://plantuml.sourceforge.net/sequence.html
Intercepting the SAP standard UML generation
So in transaction SAT there is the possibility to generate your own JNet UML sequence diagram (this exists as standard.)
However, it does not allow you to do things like filter out standard SAP routines (as far as I know! If anyone can tell me how to do this (without needing to list every method I call, please let me know!) When I was looking at one of my examples, where I ran a program to generate a performance review document for an employee, there were over 100,000 different routines called. Only about 400 of those calls involved my code, so you can imagine generating a UML diagram for the whole 100,000 calls would be a bit of overkill (not to mention an impossible to read diagram).
In customer systems there is a function module ATRA_UML_DECIDER that has been purposely handicapped. One does have to wonder why this has been done, but nevertheless it has. It allows the user to chose from a list of potential UML extraction routines. All of these routines implement the IF_ATRA_UML_TOOL interface. There are classes for extracting to JNet, Borland Together and Altova. Now, I’m sure that Borland and Altova have good products, it’s just that I don’t really want to spend money on then when there are perfectly good (for my tasks) free and open source products out there.
There is a factory class/method CL_ATRA_UML_FACTORY that creates an instance of a class implementing the interface. I overrode this method to use my particular extractor if it was me running the code. In the future, I might enhance this to check for a user role, or perhaps a user parameter, that’s trivial, the main point will be to allow others to access this logic too.
The guts of the code
Simply my implementation of the interface reads the table of data that is passed to the interface, removes all calls that aren’t to or from custom code and then builds a PlantUML representation of that code.
Here’s a very simple output that generates the diagram above.
@startuml hide footbox autonumber participant "Instance 1 of Class\nZCL_HR_EMPLOYEE" as 1 1 -> 1: Call method GET_HELD_QUALIFICATIONS activate 1 1 -> 1: Call method ZCL_HR_OBJECT->GET_RELATIONSHIPS activate 1 create "Static Methods of Class\nCL_HRBAS_READ_INFOTYPE" as 2 1 -> 2: Call method GET_INSTANCE activate 2 2 --> 1 deactivate 2 create "Instance 1 of Class\nCL_HRBAS_READ_INFOTYPE" as 3 1 -> 3: Call method IF_HRBAS_READ_INFOTYPE~READ_PLAIN_1001 activate 3 3 --> 1 deactivate 3 1 --> 1 deactivate 1 create "Instance 1 of Class\nZCL_HR_QUALIFICATION" as 4 1 -> 4: Create instance of class ZCL_HR_QUALIFICATION activate 4 4 -> 4: Call method ZCL_HR_OBJECT->CONSTRUCTOR activate 4 create "Function Group\nRHS0" as 5 4 -> 5: Call FM RH_GET_ACTIVE_WF_PLVAR activate 5 5 --> 4 deactivate 5 4 --> 4 deactivate 4 4 --> 1 deactivate 4 deactivate 1 @enduml
A slightly less trivial example
The following code does some pretty simple stuff, it finds who is my manager, and finds out what required qualifications my position/job has.
DATA: lo_emp TYPE REF TO zcl_hr_employee, lt_managers TYPE ztthr_employee_objects, lt_required_quals TYPE ztthr_qualifications. TRY. lo_emp = zcl_hr_employee=>get_employee_by_user_id( sy-uname ). lt_managers = lo_emp->get_position( )->get_managers_recursive( ). lt_required_quals = lo_emp->get_position( )->get_required_qualifications( ). CATCH zcx_hr_no_managing_pos_found ” No managing position found zcx_hr_no_holders_found ” no holders for position found. zcx_hr_no_position_found ” no position found zcx_hr_user_id_not_found. ” cannot find user id for employee ENDTRY.
So I thought I’d trace it:
it works out at around 200,000 different routines being called. 62 of those are my code, the rest standard.
First of all, I need to schedule a trace for myself…
Need to know which session I will be recording. If I left it as “Any” it will start recording this session, not very useful!
Session 2 it is!
actually run it now!
and the schedule status changes to executed.
I now need to delete the scheduled measurement. Despite the intimidating words, this does not delete my measurement, just the scheduling of it.
now swapping to the “Evaluate” tab in SAT I can see my measurement, and I can click to output to UML
Late breaking discovery! – Filter data using SLAD!
In a somewhat surprising discovery, I found that I can filter the results of the trace so that only the custom code bits get processed in UML handling routines. This speeds up the processing immensely. HOWEVER! This does mean that you will NOT see where your code calls the SAP standard code, but for some diagramming tasks this would be fine.
Clicking on the button triggers a bit of a pause whilst the system code chugs away and does loads of stuff it doesn’t need to do…
Save the data and PlantUML starts converting it immediately:
and the result:
Would probably have been a little bigger if my employee had a job assigned to their position, but you can see how incredibly easy this now makes documenting the functionality I’ve built.
After checking the SCN T&C and finding similar (if not worse conditions for the upload of SAP derivative code (it uses an SAP standard interface, so it probably is)) and the same indemnity clauses that make me refuse to participate in Code Exchange, I’ve decided not to share the code here. That said if someone else is willing to put the code out there on Code Exchange I’m more than happy to provide it to them. Perhaps someone will put their hand up to load it into Code Exchange – Gregor Wolf ???
This content was previously published on my own blog, but the tip about the SLAD filter wasn’t, and certainly the code wasn’t published there. Some excellent points have been raised about how this isn’t a replacement for actually documenting the functionality of the code that has been built. But, I have found at least one case where using this tooling has helped me write a better bit of code by sharing references to objects that I didn’t realise were being instantiated multiple times. Could something like this help you with your doco? Do you have any thoughts?
I must say this comes in handy right now - not a day early, too.
That's exactly what our management guys want to see in the weekly meetings; and your post will save me a lot of time 🙂
hopefully I can make your life even easier - I just posted the code I used at:
Somewhat ridiculously, as discussed over here:Share and share alike there isn't a space in SCN for sharing code that does not come with terms and conditions that are (in my view) unacceptable for an individual to contribute under.
I'm glad that this is helpful for you! 🙂
It looks really interesting...
I'll give it a try thank you for sharing!
No worries - let me know how you go.
I recently had an issue generating a diagram that had over 50 participants in it - think that PlantUML has some issue with very large diagrams (not that a diagram that large would be readable anyway! But other than that it seems to work quite nicely.
Really it is a good one.
Thanks for sharing.
This looks really interesting. Thanks for posting!
However, while trying it on an ABAP 7.31 EHP6 server, I noticed that from the source code you posted the type definitions for TY_OBJECT and TY_CALL_STACK (+ the corresponding table types) were missing. I just added them.
In addition, I could not find the UML generation button in SAT. Is there some configuration missing?
how right you are:
TYPES: begin of ty_call_stack,
code type i,
sap_code type i,
end of ty_call_stack,
ty_call_stack_tab TYPE STANDARD TABLE OF ty_call_stack.
TYPES: begin of ty_object,
object TYPE text40,
object_type type text4,
instance type i,
code type i,
end of ty_object,
ty_object_tab type STANDARD TABLE OF ty_object.
Here you go,
Bit confused as to why the UML button might be missing... it could possibly be that it is checking if you have JNet installed in your GUI. It's always there on the different systems when I look.
The system I built this on was a 7.31 EhP6 system so don't think it's a stack level thing.
Might be worth noting that for very large diagrams you can increase the Java heap size to allow plantUML to process them - use cmd line parameter like
C:\plantuml>"C:\Program Files (x86)\Java\jre7\bin\java" -Xmx1g -jar plantuml.jar -v -gui
managed to get some diagrams that weren't rendering to draw 🙂
I also am finding a few buglets in the code - so am having to do a little manual editing of generated file - but generally not too much.
If anyone finds an error in the code, and has a fix, please do let me know!
Good Work 🙂 ....
This would make my work as an architect a lot easier.
I could just code whatever I need, and the export the diagrams.
But then again, it's the opposite of what I'm supposed to do.
I really should make the UML diagrams upfront, and then implement them.
In such case, I wouldn't even need the UML export.
you'd be surprised though how often I'm asked to make a diagram for something that has already been build...
If a real construction architect would come in such situation, I'm pretty sure that they won't take the job, and the building will probably collapse in the short term.
for me the real use is in supporting the solution, not in explaining how it should be built (if you have to use detailed interaction diagrams to do that, then you've probably already lost.)
One should also consider however, that many successful agile solutions are built without detailed specs before the build (they also tend not to document). But in the case that you have a so-called "quality control" busy-body, then loading them up with diagrams often helps.
Whilst a building architect would be a fool to start building a sky-scraper without a plan, he does not have the benefit of being able to create his product iteratively or being able to refactor it on the go!
Again, I'll point out - to me one of the best bit of the solution was being able to visualise the flow of my code and from that make some simple tweeks that saved a lot of unnecessary logic being executed. Without the diagram, it would have been reasonably tricky to find those points where the code could be enhanced.
It probably sounds clichéd by now, still this is real exciting stuff!
I have one question though, does this work only on SAP NW 731 and plus levels only?
We are on SAP NW 702 and are due to upgrade not any sooner, so was wondering if I can still use this functionality. I dont see the UML generator button in SAT transaction now. If you can also add this info of the bare bones minimum required level of SAP NW to enjoy this useful functionality?
I'm pretty sure the functionality is there in 7.02 not sure about 7.01 or below. I'll have a quick check today, but think there is a routine that checks what you have installed that hides/shows the generate uml button. Let me get back to you...
As Srikanth mentioned, cannot see the button in SAT. We are also on 702. Appreciate, if you can help us in activating the button.
Thank you so much for the nice article.
Thanks for the useful info on smart documentation.
We have SAP NetWeaver AS ABAP 7.31, and yet the generate UML button is nowhere to be seen. Searching for this on SCN and the web, but no luck. If you could help out on this, would really appreciate it.
Thanks and Happy new year,
Hi Parimal, we have a server of NetWeaver 7.40 and unfortunately we cannot find the generate UML button in transaction SAT either. However, in SE80 we can do a 'Display UML' for objects of package. I guess that the UML function in SAT was disabled currently in SAT in some one support package, or is disabled due to front-end SAPGUI update. Still unsure.
I have encountered "JNet OCX is missing(Wrong GUI version)" error message. I am looking into it to get this resolved.
Thanks for the info though,
For those who are also interested in UML diagram function in SAT in release 740: double confirmed from Netweaver basis developer that this will not be provided in release 740...(not sure about future release if any)
seems such a helpful function was demised forever somehow.
Thanks for this work.
I have been using Visio for UML documentation using class and sequence diagrams. Your blog has leaded me to check alternatives. At least in 7.40 there is also an interface IF_UML_TOOL_PLUGIN for custom class diagram output (plugin) that is easy to handle. Let us see who will be the first to post a PlantUML version.
Note that the option to display a trace as UML is only available if a measurement was performed without aggregation. Under Settings, create a new variant (or change the existing one) and set the parameter "Aggregation" to None. I could verify the option is still available in 7.40 SP05.
There is a problem with the size of the sequence diagram generated for a real scenario. No matter if the output is JNet or PlantUML, the diagram tends to be too large to be useful. I propose to shrink the diagram size by automatically recognizing LOOPs in the call stack and generating one UML Loop block instead of, say 100x the same sequence of calls.
I assume a logic with the complexity of a substring search would help here, but I have been wrong before.
Meanwhile, I have refactored your code for Netweaver 7.40 SP05. Of course I own all the new bugs and there is no guarantee.
Thanks for the useful WiKi - ABAP Trace to PlantUML Sequence Diagram - Code Gallery - SCN Wiki.
Can you attach the .nugg (SAPlink) files for the include? I propose this because this include is very big and copy-pasting it is a bit tedious 🙂
Double-click on code will select whole code.
Idle mouse cursor on code also shows this tip as tooltip text.
Yeah, i realised it after i posted my comment. But if you are working on IE (meh 😐 ) on a Citrix virtual desktop (meh meh 😐 ) it's a pain to do this thing.
Therefore, i thought that my request for the NUGG file makes sense 😎
the nugget is now attached (thanks to Manish).. yummy if you are on 7.4 SP05+.