We decided to invest in a new functionality which will help our customers to run ABAP code easily and for free.
Let’s see what ChatGPT thinks about this topic.
It looks like it is not aware of the latest features which were recently added to the Kronos by codbex.
Kronos gives you the possibility to run easily ABAP code in a few minutes.
You can use any database which is supported, like H2, PostgreSQL, MySQL, Snowflake, HANA etc.
Let’s see how easy it is.
Running a simple ABAP code using Kronos
Let’s say we have the following ABAP class zcl_employee_dao.clas.abap
and we want to run it.
CLASS zcl_employee_dao DEFINITION PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_employee,
id TYPE n LENGTH 10,
first_name TYPE string,
last_name TYPE string,
END OF ty_employee,
ty_employees TYPE STANDARD TABLE OF ty_employee WITH DEFAULT KEY.
CLASS-METHODS:
delete_all_employees,
select_all
RETURNING VALUE(rv_result) TYPE string,
insert_employee,
update_employee_last_name.
ENDCLASS.
CLASS zcl_employee_dao IMPLEMENTATION.
METHOD delete_all_employees.
DATA: lv_rc TYPE i.
DELETE FROM employees WHERE id > 0.
lv_rc = sy-dbcnt.
IF lv_rc > 0.
WRITE: / 'All employees deleted successfully.'.
ELSE.
WRITE: / 'No employees found to delete.'.
ENDIF.
ENDMETHOD.
METHOD select_all.
DATA: lt_employees TYPE ty_employees,
lv_json TYPE string.
SELECT id first_name last_name
FROM employees
INTO TABLE lt_employees.
WRITE: / 'Employees selected.'.
ENDMETHOD.
METHOD insert_employee.
DATA: wa_employee TYPE ty_employee.
wa_employee-id = 1.
wa_employee-first_name = 'Jane'.
wa_employee-last_name = 'Doe'.
INSERT INTO employees VALUES wa_employee.
IF sy-subrc = 0.
WRITE: / 'Employee inserted successfully.'.
ELSE.
WRITE: / 'Failed to insert employee.'.
ENDIF.
ENDMETHOD.
METHOD update_employee_last_name.
DATA: lv_rc TYPE i.
UPDATE employees
SET last_name = 'Smith'
WHERE id = 1.
lv_rc = sy-dbcnt.
IF lv_rc > 0.
WRITE: / 'Employee last name updated successfully.'.
ELSE.
WRITE: / 'Failed to update employee last name.'.
ENDIF.
ENDMETHOD.
ENDCLASS.
It is a simple DAO for employees management, which uses ABAP inline SQL with hardcoded data for simplicity.
To run this ABAP code, follow the steps bellow or watch the recorded video.
- Start a Kronos instance using Docker
Open your terminal and execute the following:docker run --name codbex-kronos --rm -p 80:80 \ -v ./dirigible:/target/dirigible \ ghcr.io/codbex/codbex-kronos:1.1.1 # use version 1.1.1 or later
- Open Kronos and create a simple ABAP Starter project
- Open Kronos at http://localhost
- Login using the default user - username:
admin
, password:admin
- At the
Welcome
view search forABAP
and selectABAP Starter
template
- Type project and file name - for example
my-first-abap-project
and click onOk
button
- An ABAP starter project will be automatically generated
- Let’s see the most important files in the generated project
src/abap
folder is the place where your ABAP code must be placed.src/abap/zcl_abap_app.clas.abap
is a class which has methodrun
which is the entry point of your application.
Similar to the main method in Java.
By default, there is a call to the Kronos ABAP API which prints the stringHello world!
to the http response.
Here you can place the calls to your ABAP methods.src/run.mjs
is the JavaScript entry point which initializes the ABAP and calls the transpiled ABAP classzcl_abap_app.clas.abap
.
Yes, that’s right, the ABAP code is transpiled which makes it easy to use it from JavaScript or TypeScript.abap_transpile.json
andabaplint.json
are configuration files which are used for the transpilation and automated code checking (linting) of the ABAP code.
- Next, you have to publish the project by clicking the
Publish all
button. It is required when you make code changes to take effect.
- Now, let’s check whether the generated project works.
- Refresh the workspace using the
Refresh
button
- Navigate to
dist/run.mjs
file and double-click on it - You should see
Hello world!
in thePreview
tab.
If it is easier for you, you can open http://localhost/services/js/my-first-abap-project/dist/run.mjs in your browser.
The result will be the same.
- Refresh the workspace using the
- Add DAO ABAP class
zcl_employee_dao.clas.abap
- Right-click on
src/abap
and selectNew
->File
- Type
zcl_employee_dao.clas.abap
- Open the file by double-clicking on it and paste the file content
- Save the file (
cmd + S
orctrl + S
)
- Right-click on
- Create
employees
table
To work this class, we are going to need a table for the employees.
We will use some codbex functionalities to simplify the things.
Once the project is published, the table will be automatically created in the configured Database (which by default is H2).
Create a file calledemployee.table
in foldersrc/db
with the following content:{ "name": "employees", "type": "TABLE", "columns": [ { "name": "id", "type": "INTEGER", "length": "0", "nullable": "false", "primaryKey": "true", "defaultValue": "" }, { "name": "first_name", "type": "VARCHAR", "length": "50", "nullable": "false", "primaryKey": "false" }, { "name": "last_name", "type": "VARCHAR", "length": "50", "nullable": "false", "primaryKey": "false" } ] }
- Due to an issue in the ABAP transpiler (which will be fixed soon), we have to register the table in the ABAP context manually.
To do that, edit thesrc/run.mjs
with the followingimport { DatabaseInitializer } from "sdk/abap/database"; import { initializeABAP } from '../dist/abap/init.mjs'; import { zcl_abap_app } from '../dist/abap/zcl_abap_app.clas.mjs'; async function initialize() { DatabaseInitializer.initDefaultDataSource(); await initializeABAP(); // manually register the table abap.DDIC.EMPLOYEES = { "objectType": "TABL", "type": { "value": { "offset": { "value": 0, "qualifiedName": "I" }, "length": { "value": 0, "qualifiedName": "I" } }, "qualifiedName": "employees", "ddicName": "employees", "suffix": {}, "asInclude": {} }, "keyFields": ["id"] }; } await initialize(); await zcl_abap_app.run();
- Next step is to use the DAO in the
run
method
Opensrc/abap/zcl_abap_app.clas.abap
and replace the content with the following:CLASS zcl_abap_app DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. CLASS-METHODS: run. ENDCLASS. CLASS zcl_abap_app IMPLEMENTATION. " this is the main method called by run.mjs METHOD run. zcl_employee_dao=>delete_all_employees( ). zcl_employee_dao=>insert_employee( ). zcl_employee_dao=>select_all( ). zcl_employee_dao=>update_employee_last_name( ). ENDMETHOD. ENDCLASS.
- Now, we have to publish the project to create the defined table and transpile the ABAP code
- Check the execution result
- Once published, open http://localhost/services/js/my-first-abap-project/dist/run.mjs.
You should receive status code200
and console output like the following:
- You can check the table content as well.
- Go to
Database
perspective
- Expand
PUBLIC
schema forDefaultDB
, right-click onemployees
table and click onShow Contents
- You should see that the hardcoded employee was inserted and the last name was updated
- Go to
- Once published, open http://localhost/services/js/my-first-abap-project/dist/run.mjs.
- We can refactor the DAO a bit in order to use the Kronos ABAP API for printing lines to the http response instead of the console.
- Replace the content of
src/abap/zcl_employee_dao.clas.abap
with the following
- Replace the content of
CLASS zcl_employee_dao DEFINITION PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_employee,
id TYPE n LENGTH 10,
first_name TYPE string,
last_name TYPE string,
END OF ty_employee,
ty_employees TYPE STANDARD TABLE OF ty_employee WITH DEFAULT KEY.
CLASS-METHODS:
delete_all_employees,
select_all
RETURNING VALUE(rv_result) TYPE string,
insert_employee,
update_employee_last_name.
ENDCLASS.
CLASS zcl_employee_dao IMPLEMENTATION.
METHOD delete_all_employees.
DATA: lv_rc TYPE i.
DELETE FROM employees WHERE id > 0.
lv_rc = sy-dbcnt.
IF lv_rc > 0.
zcl_codbex_http_response=>println(
EXPORTING
message_in = 'All employees deleted successfully.' ).
ELSE.
zcl_codbex_http_response=>println(
EXPORTING
message_in = 'No employees found to delete.' ).
ENDIF.
ENDMETHOD.
METHOD select_all.
DATA: lt_employees TYPE ty_employees,
lv_json TYPE string.
SELECT id first_name last_name
FROM employees
INTO TABLE lt_employees.
zcl_codbex_http_response=>println(
EXPORTING
message_in = 'Employees in DB:' ).
zcl_codbex_http_response=>println(
EXPORTING
message_in = lt_employees ).
WRITE: / 'Employees selected.'.
ENDMETHOD.
METHOD insert_employee.
DATA: wa_employee TYPE ty_employee.
wa_employee-id = 1.
wa_employee-first_name = 'Jane'.
wa_employee-last_name = 'Doe'.
INSERT INTO employees VALUES wa_employee.
IF sy-subrc = 0.
zcl_codbex_http_response=>println(
EXPORTING
message_in = 'Employee inserted successfully.' ).
ELSE.
zcl_codbex_http_response=>println(
EXPORTING
message_in = 'Failed to insert employee.' ).
ENDIF.
ENDMETHOD.
METHOD update_employee_last_name.
DATA: lv_rc TYPE i.
UPDATE employees
SET last_name = 'Smith'
WHERE id = 1.
lv_rc = sy-dbcnt.
IF lv_rc > 0.
zcl_codbex_http_response=>println(
EXPORTING
message_in = 'Employee last name updated successfully.' ).
ELSE.
zcl_codbex_http_response=>println(
EXPORTING
message_in = 'Failed to update employee last name.' ).
ENDIF.
ENDMETHOD.
ENDCLASS.
- Publish the project and open http://localhost/services/js/my-first-abap-project/dist/run.mjs.
- Now, the logs of the execution will be returned in the http response
This is how we ran our existing ABAP code using Kronos in a few quick steps.
Summary
Let’s summarize what you can do with Kronos
- you can easily run ABAP code in Kronos
- it costs you nothing since Kronos is open source project
- licenses are not required
- you can use any database which is supported, like H2, PostgreSQL, MySQL, Snowflake, HANA etc.
- your ABAP code can run on any modern container platform
- the code can be executed locally as well
- if you have an ABAP application with thousands of lines of code but no ABAP developers, you can still use the existing ABAP code and call it from JavaScript or TypeScript.
- you can use the comprehensive codbex SDK which uses different modern open source projects for messaging, jobs scheduling, REST, OData, mails etc.
- if you want to use the SDK directly in your ABAP code, there is a Kronos ABAP which will provide all the SDK functionalities
- your application can benefit from the codbex platform, tooling and modules
- you can integrate your ABAP code with the Kronos SAP HANA XS compatibility functionalities
- to reduce the operational cost, you get multitenancy out of the box
- and much more
Note that this functionality is relatively new.
There may be some ABAP functionalities which will not work but the journey has just begun.
We are willing to support you!
The project we implemented can be found in this GitHub project.
Credits
Special thanks to the contributors who implemented open-abap and abaplint.
Without these projects, this Kronos functionality wouldn’t be possible.
I hope you enjoyed this blog. Stay tuned for more great functionality by codbex!
If you have any questions, ideas or want to contribute, feel free to contact us.