How can I react to the activation of a class in ABAP?
I’d like to write custom metadata and generate other classes when an ABAP class gets changed and activated. For example, I’d like to scan the class’s source code for TODO comments and store them in a custom table.
Is there a way to detect that a class is activated and react to it?
I looked for BAdIs, but in vain. There are BAdIs to react to transport releases, of course, but that happens much later.
I see only two ways to “solve” this, both bad: either I plan a recurring job and do that there (would have to run very often to get near real-time), or I illegally invade the activation code with extension points and cross fingers that it won’t break.
See also questions close to this topic
What's the shortest notation to split an ABAP internal table into several smaller tables?
In ABAP, I have a pretty large internal table, say 31,000 rows. What's the shortest and most efficient way to split that into multiple smaller tables of fixed size, say 1,000 rows each?
Naive way would be:
DATA lt_next_package TYPE tt_table_type. LOOP AT it_large_table INTO DATA(ls_row). INSERT ls_row INTO TABLE lt_next_package. IF lines( lt_next_package ) >= lc_package_size. INSERT lt_next_package INTO TABLE rt_result. CLEAR lt_next_package. ENDIF. ENDLOOP. IF lt_next_package IS NOT INITIAL. INSERT lt_next_packge INTO TABLE rt_result. ENDIF.
That works and is rather efficient, but looks cumbersome, esp. the don't-forget-the-last-package section at the very end. I believe there must be a better way to do this with the newer ABAP mesh paths and table expressions, but so far couldn't come up with one.
Field "GET_ATTRIBUTE(" is unknown. It is neither in one of the specified tables nor defined by a "DATA" statement
I'm working on my first webdynpro application. I used the wizard to call a function module from my componentcontroller. I used another wizard to call the componentcontroller method from a view method. After that I tried to use node attributes as arguments, but I'm getting the error that's in the title. The error is pointing at the first argument (Activestatus).
This is the code of the view method.
method DOREFRESHDATA . DATA lo_nd_filternode TYPE REF TO if_wd_context_node. DATA lo_el_filternode TYPE REF TO if_wd_context_element. lo_nd_filternode = wd_context->get_child_node( name = wd_this->wdctx_filternode ). lo_el_filternode = lo_nd_filternode->get_element( ). DATA lo_componentcontroller TYPE REF TO ig_componentcontroller . lo_componentcontroller = wd_this->get_componentcontroller_ctr( ). lo_componentcontroller->execute_getorders( activestatus = lo_el_filternode->get_attribute( name = 'ACTIVESTATUS' ) batch = GETFILTERSTRING( ATTRIBUTENAME = 'BATCH' ) cancelstatus = lo_el_filternode->get_attribute( name = 'CANCELSTATUS' ) completestatus = lo_el_filternode->get_attribute( name = 'COMPLETESTATUS' ) confirmstatus = lo_el_filternode->get_attribute( name = 'CONFIRMSTATUS' ) enddate = lo_el_filternode->get_attribute( name = 'STARTDATEENDDATE' ) endtime = lo_el_filternode->get_attribute( name = 'STARTDATEENDTIME' ) equipment = GETFILTERSTRING( ATTRIBUTENAME = 'EQUIPMENT' ) financialstatus = lo_el_filternode->get_attribute( name = 'FINANCIALSTATUS' ) materialdescription = GETFILTERSTRING( ATTRIBUTENAME = 'MATERIALDESCRIPTON' ) materialnumber = GETFILTERSTRING( ATTRIBUTENAME = 'MATERIALDESCRIPTION' ) order = GETFILTERSTRING( ATTRIBUTENAME = 'ORDERNUMBER' ) orderplopo = lo_el_filternode->get_attribute( name = 'ORDERTYPE' ) ordertype = GETFILTERSTRING( ATTRIBUTENAME = 'PROCESAREA' ) plannedstatus = GETFILTERSTRING( ATTRIBUTENAME = 'PLANNEDSTATUS' ) startdate = lo_el_filternode->get_attribute( name = 'STARTDATESTARTDATE' ) starttime = lo_el_filternode->get_attribute( name = 'STARTDATESTARTTIME' ) technicalstatus = lo_el_filternode->get_attribute( name = 'TECHNICALSTATUS' ) ). endmethod.
Is it illegal to call a function as argument and do I have to create a local variable for each argument or is something else going wrong.
I'm new to ABAP and Webdynpro. Thank you for your help.
Is there an efficient way to avoid instantiating a class with syntax errors?
As you may know, it is pretty easy to have active code of a class containing syntax errors (someone activated the code ignoring syntax warnings or someone changed the signature of a method the class calls, for instance).
This means that also dynamic instantiation of such a class via
CREATE OBJECT my_object TYPE (class_name).
will fail with an apparently uncatchable SYNTAX_ERROR exception. The goal is to write code that does not terminate when this occurs.
Wrap the CREATE OBJECT statement inside an RFC function module, call the module with destination NONE, then catch the (classic) exception SYSTEM_FAILURE from the RFC call. If the RFC succeeds, actually create the object (you can't pass the created object out of the RFC because RFC function modules can't pass references, and objects cannot be passed other than by reference as far as I know).
This solution is not only inelegant, but impacts performance rather harshly since an entirely new LUW is spawned by the RFC call. Additionally, you're not actually preventing the SYNTAX_ERROR dump, just letting it dump in a thread you don't care about. It will still, annoyingly, show up in ST22.
Before attempting to instantiate the class, call
cl_abap_typedescr=>describe_by_name( class_name )
and catch the class-based exception CX_SY_RTTI_SYNTAX_ERROR it throws when the code it attempts to describe has syntax errors.
This performs much better than the RFC variant, but still seems to add unnecessary overhead - usually, I don't want the type information that
describe_by_namereturns, I'm solely calling it to get a catchable exception, and when it succeeds, its result is thrown away.
Is there a way to prevent the SYNTAX_ERROR dump without adding such overhead?