2025 Jun 04 10:06 AM - edited 2025 Jun 04 11:56 AM
I have not been able to find a way to retain Static Class attributes in instance memory between SAPUI5 apps and the ABAP backend. We're currently on a S/4 HANA on-premise 2023 FSP 02 system. On each call to the ABAP backend from SAPUI5, all of my static class attributes are cleared. Nothing is kept in ABAP memory between calls the ABAP backend from my UI5 apps.
How can we retain ABAP class instances in memory while re-designing our UI to run on SAPUI5? I hope that I am missing a setting to keep an ABAP internal session memory alive. If not, this is a really big issue for partners and customers that cannot leverage there instanciated instances without having to rebuild from the DB on every call to the ABAP Server. SAPUI5 apps need to be able to leverage instantiated classes in the ABAP server.
oData services have become the primary bridge between frontend and backend apps. However, OData can't support ABAP object references, so we need to get a little more creative on how to make the two technologies work together:
Attempt 1 - Custom CDS entities + ABAP data store. Here we set up a data store as a singleon to try to take advantage of static attribute - FAILED
class ZCL_LE_DATA_STORE definition
public
final
create public .
public section.
class-methods GET_OBJECT
returning
value(RO_DATA_STORE) type ref to ZCL_LE_DATA_STORE .
methods GET_FOO_OBJECT
returning
value(RO_FOO) type ref to ZCL_FOO.
methods SET_FOO_OBJECT
importing
!IO_FOO type ref to ZCL_FOO .
METHODS get_count
RETURNING
VALUE(rv_count) TYPE int4.
METHODS set_count
IMPORTING
iv_count TYPE int4.
PROTECTED SECTION.
private section.
class-data MO_DATA_STORE type ref to ZCL_LE_DATA_STORE .
DATA MO_FOO type ref to ZCL_FOO .
DATA mv_count TYPE int4.
ENDCLASS.
CLASS ZCL_LE_DATA_STORE IMPLEMENTATION.
METHOD get_object.
IF zcl_le_data_store=>mo_data_store IS NOT BOUND.
CREATE OBJECT zcl_le_data_store=>mo_data_store.
ENDIF.
ro_data_store = zcl_le_data_store=>mo_data_store.
ENDMETHOD.
METHOD get_count.
rv_count = mv_count.
ENDMETHOD.
METHOD set_count.
mv_count = iv_count.
ENDMETHOD.
METHOD GET_FOO_OBJECT.
ro_foo = mo_foo.
ENDMETHOD.
METHOD SET_FOO_OBJECT.
mo_foo = io_foo.
ENDMETHOD.
ENDCLASS.
METHOD if_rap_query_provider~select.
TRY.
DATA(lo_data_store) = zcl_le_data_store=>get_object( ).
DATA(lv_count) = lo_data_store->get_count( ).
lv_count += 1.
lo_data_store->set_count( lv_count ).
"Required calls for if_rap_query_provider interface usage
DATA(lv_top) = io_request->get_paging( )->get_page_size( ).
DATA(lv_skip) = io_request->get_paging( )->get_offset( ).
DATA(lt_fields) = io_request->get_requested_elements( ).
DATA(lt_sort) = io_request->get_sort_elements( ).
DATA(lt_filter_conds) = io_request->get_filter( )->get_as_ranges( ). " get_filter_conditions( ).
DATA lt_data TYPE ty_web_api_t.
io_response->set_total_number_of_records( lines( lt_data ) ).
io_response->set_data( lt_data ).
CATCH cx_root INTO DATA(exception).
DATA(exception_message) = cl_message_helper=>get_latest_t100_exception( exception )->if_message~get_longtext( ).
ENDTRY.
ENDMETHOD.The get data store method is returning an unbound instance on each call to if_rap_query_provider.
Attempt 2 - ABAP Push Channels - FAILED
I extended Gregor's ABAP push channel example to allow PCP messaging between the SAPUI5 app and the ABAP server. Unfortanately, the data store static attributes do not retain instance memory over ABAP message Channels. The results are the same as attempt #1.
To add insult to injury, when moving this approach from Z-space to a ABAP Cloud, SAP ABAP Messaging Channel Application (t-code SAPC) are not supported in ABAP Cloud. I created another Tech Q&A post on this specific issue here.
CLASS zcl_apc_wsp_ext_zapc_echo DEFINITION
PUBLIC
INHERITING FROM cl_apc_wsp_ext_stateless_pcp_b
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS if_apc_wsp_ext_pcp~on_message
REDEFINITION .
METHODS if_apc_wsp_ext_pcp~on_start
REDEFINITION .
PROTECTED SECTION.
private section.
class-methods PREPARE_MESSAGE_FOR_UI
importing
!IV_TEXT type STRING
returning
value(RV_TEXT) type STRING .
ENDCLASS.
CLASS ZCL_APC_WSP_EXT_ZAPC_ECHO IMPLEMENTATION.
METHOD if_apc_wsp_ext_pcp~on_message.
DATA: lo_producer TYPE REF TO cl_amc_message_type_pcp.
DATA: lt_fields TYPE pcp_fields.
DATA lt_foo TYPE zcl_foo=>ty_fo_tab.
TRY.
* retrieve the text message
i_message->get_fields( CHANGING c_fields = lt_fields ).
lo_producer ?= cl_amc_channel_manager=>create_message_producer(
i_application_id = 'ZAMC_ECHO'
i_channel_id = '/echo' ).
DATA lo_foo TYPE REF TO zcl_foo.
READ TABLE lt_fields INTO DATA(ls_foo_guid) WITH KEY name = 'foo_guid'.
IF sy-subrc NE 0.
"Raise exception
ENDIF.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
TRY.
READ TABLE lt_fields INTO DATA(ls_fields) WITH KEY name = 'operation'.
DATA(lv_message) = i_message->get_text( ).
data lo_data_store TYPE REF TO zcl_le_data_store.
lo_foo = zcl_le_data_store=>get_foo_object( ).
IF lo_foo IS NOT BOUND.
"Object memory not working, rebuild from DB :(
lo_foo = zcl_foo_factory=>find_or_create( ls_doc_guid-value ).
ENDIF.
CASE ls_fields-value.
WHEN 'update_foo'.
lo_foo->_service( lv_message ).
"lo_foo->save( i_commit = 'X' ).
WHEN 'handle_save_and_commit'.
lo_foo->save( i_commit = 'X' ).
WHEN OTHERS.
ENDCASE.
CATCH cx_root.
"Raise exception
ENDTRY.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
DATA(lv_text) = prepare_message_for_ui( 'Success' ).
DATA(lo_msg) = cl_ac_message_type_pcp=>create( ).
lo_msg->set_text( i_message = lv_text ).
LOOP AT lt_fields INTO DATA(ls_field).
IF ls_field-name NP 'pcp-*'.
lo_msg->set_field( i_name = ls_field-name i_value = ls_field-value ).
ENDIF.
ENDLOOP.
lo_producer->send( i_message = lo_msg ).
CATCH cx_ac_message_type_pcp_error INTO DATA(lx_pcp_error).
MESSAGE lx_pcp_error->get_text( ) TYPE 'E'.
CATCH cx_amc_error INTO DATA(lx_amc_error).
MESSAGE lx_amc_error->get_text( ) TYPE 'E'.
CATCH cx_apc_error INTO DATA(lx_apc_error).
MESSAGE lx_apc_error->get_text( ) TYPE 'E'.
CATCH /coss/cx_api_hub INTO DATA(lx_api_hub).
MESSAGE lx_api_hub->get_text( ) TYPE 'E'.
ENDTRY.
ENDMETHOD.
METHOD if_apc_wsp_ext_pcp~on_start.
TRY.
* bind the WebSocket connection to the AMC channel
DATA(lo_binding) = i_context->get_binding_manager( ).
lo_binding->bind_amc_message_consumer(
i_application_id = 'ZAMC_ECHO'
i_channel_id = '/echo' ).
CATCH cx_apc_error INTO DATA(lx_apc_error).
DATA(lv_message) = lx_apc_error->get_text( ).
MESSAGE lx_apc_error->get_text( ) TYPE 'E'.
ENDTRY.
ENDMETHOD.
METHOD prepare_message_for_ui.
TYPES: BEGIN OF t_message,
text TYPE string,
user TYPE uname,
date TYPE timestamp,
END OF t_message.
DATA: ls_message TYPE t_message.
ls_message-text = iv_text.
ls_message-user = sy-uname.
GET TIME STAMP FIELD ls_message-date.
DATA(lo_json_witer) = cl_sxml_string_writer=>create(
type = if_sxml=>co_xt_json
).
CALL TRANSFORMATION id SOURCE ls_message = ls_message
RESULT XML lo_json_witer.
DATA(lv_xstr) = lo_json_witer->get_output( ).
CALL FUNCTION 'ECATT_CONV_XSTRING_TO_STRING'
EXPORTING
im_xstring = lv_xstr
* im_encoding = 'UTF-8'
IMPORTING
ex_string = rv_text.
ENDMETHOD.
ENDCLASS.
Attempt 3 - ABAP Daemons could be used in combination with any approach that allows communication between SAPUI5 & the ABAP backend and should be able to set and retrieve instanciated objects as a Static Attribute. However, The ABAP dependency (CL_ABAP_DAEMON_EXT_BASE) to make use of ABAP Daemons is also not released for use an ABAP Cloud.
Attempt 4 - ABAP Shared memory to the rescue? NOPE, This approach can also be used in any combination of SAPUI5 <-> ABAP Cloud communication. Similarly, the ABAP dependencies to make use of this approach are also not released for ABAP Cloud usage (CL_SHM_AREA, if_shm_build_instance & transaction SHMA objects). While this approach does work in non ABAP Cloud, a limitation I came accross is the "cx_shm_external_reference" exception which prevents you from setting an instance ref to shared memory if it has creates references to other objects. For our case of an object with many other nestest instances, this approach is not workable.
After quite some research and failed attempts... getting SAPUI5 and ABAP Cloud to work together is challenging. I think we need something like ABAP Events + SAPUI5's EventBus to communicate or a ABAP Cloud based way to use ABAP Push channels. Currently migrating to clean core with the available tools of our on-prem system feels like trying to fit a square peg into a circlular hole 😪.
ps. I am running my freestyle SAPUI5 apps on Business application studio & deploying it to the ABAP Application server. In both scenerios there is not a clear way to utilize my existing ABAP classes are part of our clean core add-on.
__PRESENT
__PRESENT
__PRESENT
__PRESENT__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
__PRESENT
Request clarification before answering.
| User | Count |
|---|---|
| 12 | |
| 9 | |
| 7 | |
| 5 | |
| 4 | |
| 2 | |
| 2 | |
| 2 | |
| 2 | |
| 2 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.