Printing to ABAP console
Introduction to the ABAP Console
Perhaps you may be unfamiliar with this, but newer ABAP versions (7.52+) have the interface if_oo_adt_classrun, which allows printing to a console. This is an alternative to using WRITE statements or the cl_demo_output class. And this alternative is, IMO, a very welcome thing since pretty much all non-ABAP developers are using console printing one way or another.
Implementing this interface does more than that. It turns a class into an executable state by forcing you to implement a main method – as you would do in Java, for example. And, thanks to this, it completely bypasses the need for starting an SAP GUI everytime you want to run something – which is another great thing. To execute, you press F9 and the class starts running through its main method.
You can read some more about the topic in Horst Keller‘s article on the matter and this tutorial for creating your first ABAP console app.
Demo of the ABAP Console
What better way to demonstrate this than saying Hello, world? Here’s how we do this:
- Create a new class;
- Implement the if_oo_adt_classrun_interface;
- Use the out object to print;
- Execute with F9 to see the output in the console.
And here’s an example code following all of the steps above:
CLASS z_ptac_main DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES: if_oo_adt_classrun. ENDCLASS. CLASS z_ptac_main IMPLEMENTATION. METHOD if_oo_adt_classrun~main. out->write( 'Hello, world' ). ENDMETHOD. ENDCLASS.
And the result of executing this code with F9:
Printing to the ABAP console from another method
Now, here comes the reason for writing this article. I was running some experiments, and it was going to be very useful to see some output printed from a non-main method of the class. How do you this? Well, I couldn’t find any instructions – so I created my own workaround:
- Create an out static attribute pointer in the class which has the main method (i.e., the one implementing the if_oo_adt_classrun interface);
- Set the static attribute pointer to point to the out object from the main method;
- Now, you can print from any other method inside this class!
Here’s the example:
CLASS z_ptac_main DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES: if_oo_adt_classrun. CLASS-DATA: out TYPE REF TO if_oo_adt_classrun_out. CLASS-METHODS: hello_world. ENDCLASS. CLASS z_ptac_main IMPLEMENTATION. METHOD if_oo_adt_classrun~main. me->out = out. hello_world( ). ENDMETHOD. METHOD hello_world. out->write( 'Hello, world - but from another method!' ). ENDMETHOD. ENDCLASS.
And here’s the console output for the example:
Printing to the ABAP console from another class
If you noticed, we have made the out pointer public. This means that we could also use it from another class – like in this example:
CLASS z_ptac_dog DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. METHODS: woof. ENDCLASS. CLASS z_ptac_dog IMPLEMENTATION. METHOD woof. z_ptac_main=>out->write( 'Woof-woof!' ). ENDMETHOD. ENDCLASS.
We will still be running the logic through our class with the main method, however:
CLASS z_ptac_main DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES: if_oo_adt_classrun. CLASS-DATA: out TYPE REF TO if_oo_adt_classrun_out. ENDCLASS. CLASS z_ptac_main IMPLEMENTATION. METHOD if_oo_adt_classrun~main. me->out = out. DATA(dog) = NEW z_ptac_dog( ). dog->woof( ). ENDMETHOD. ENDCLASS.
Executing the z_ptac_main class prints the following output:
What's the use case though? Why would you want to write to the console? Is it only something that would be used for problem resolution while developing?
Indeed, problem resolution or just output testing are already great use-cases!
Honestly, there are some issues currently which prevent more advanced use-cases. Some of them are described by Fabian Lupa in the Horst Keller article linked in the post. Another one I could add is lack of input reading - there's only output printing (AFAIK).
If these cases are fixed, may be we can have full-blown command line apps as we have in Java, Python, etc. written in ABAP 🙂
I actually found this useful. I've been away from ABAP for about 6 yrs after doing it for 20+ yrs. I'm restarting with BTP ABAP until I get access to more systems with my new employer. I soon hit the brickwall of how you actually execute any code that's not in a service binding or similar, since we are very much working on classes only. Following on from that, simple output like list-processing is gone, even output stream is disallowed. ATC would be another option but has the overhead of learning the framework and unit test coding. I just wanted some simple verification that the code was running from ADT.
I discovered the out method in some samples but it was not built-in. The traced it to if_oo_adt_classrun and figured out it was restricted to main(). Was expecting to have to get a reusable reference or something that I could use through the other methods, then found that you'd done it already. So thanks for that!
p.s I noticed that the interface has a "get" too, curious!