Clean Core ist SAPs strategische Antwort auf das jahrzehntealte Problem chaotischer, upgrade-gefährdender SAP-Modifikationen. Die Kernidee: Halten Sie den SAP-Standardcode sauber (clean) und realisieren Sie Erweiterungen ausschließlich über definierte, stabile Schnittstellen.
Das Problem: Traditionelle SAP-Anpassungen
Klassische Modifikationen (Pre-Clean Core)
" ❌ SCHLECHT: Direkter Eingriff in SAP-StandardENHANCEMENT-POINT ep_vbap_check IN PROGRAM sapmv45a. " Kundeneigene Logik direkt im SAP-Standardprogramm IF vbap-matnr = 'SPECIAL'. vbap-kwmeng = vbap-kwmeng * 2. ENDIF.END-ENHANCEMENT-POINT.
" ❌ SCHLECHT: Nicht-freigegebene Tabellen/Felder nutzenSELECT SINGLE * FROM but000 WHERE partner = lv_partner." but000 ist nicht freigegeben → kann jederzeit ändern!
" ❌ SCHLECHT: User-Exits/BADIs mit unsauberem ZugriffMETHOD if_ex_badi_name~execute. " Direkter Zugriff auf interne SAP-Strukturen DATA(lv_internal) = cl_sap_internal_class=>get_data( ).ENDMETHOD.Die Folgen:
- 🔴 Upgrades werden blockiert oder brechen Anpassungen
- 🔴 Hohe Wartungskosten (durchschnittlich 30-40% des IT-Budgets)
- 🔴 Langsame Innovation (Angst vor Breaking Changes)
- 🔴 Technical Debt wächst exponentiell
Clean Core: Die Lösung
Clean Core bedeutet strikte Trennung zwischen:
- SAP Standard-Code (Core) – unangetastet
- Erweiterungen (Extensions) – nur über freigegebene APIs
┌──────────────────────────────────────────────────────┐│ SAP Standard ││ (SAP S/4HANA Core) ││ ││ ┌─────────────────────────────────────────┐ ││ │ Released APIs & Extension Points │ ││ │ (Von SAP garantiert stabil) │ ││ └──────────────┬──────────────────────────┘ │└─────────────────┼───────────────────────────────────┘ │ │ Nur über freigegebene Schnittstellen │ ┌──────────▼──────────────────────────┐ │ Clean Core Extensions │ │ │ │ • Tier-3: In-Stack (ABAP Cloud) │ │ • Key User Extensibility │ │ • Side-by-Side (BTP) │ │ • API-Integration │ └─────────────────────────────────────┘Die 3 Tiers: Extensibility Model
SAP definiert ein 3-stufiges Erweiterungsmodell:
Tier 1: Developer Extensibility (Side-by-Side)
Prinzip: Erweiterungen laufen auf SAP BTP (außerhalb von S/4HANA)
" Auf BTP ABAP Environment entwickeltCLASS zcl_btp_sales_extension DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES if_oo_adt_classrun.ENDCLASS.
CLASS zcl_btp_sales_extension IMPLEMENTATION. METHOD if_oo_adt_classrun~main. " Zugriff auf S/4HANA via OData/APIs DATA(lo_http) = cl_web_http_client_manager=>create_by_http_destination( i_destination = cl_http_destination_provider=>create_by_url( i_url = 'https://my-s4hana.com/sap/opu/odata4/sap/api_salesorder_v1' ) ).
DATA(lo_request) = lo_http->get_http_request( ). lo_request->set_header_field( i_name = 'Accept' i_value = 'application/json' ).
DATA(lo_response) = lo_http->execute( if_web_http_client=>get ). DATA(lv_json) = lo_response->get_text( ).
" Eigene Geschäftslogik " → Kein Zugriff auf S/4HANA-Interna " → Vollständig isoliert ENDMETHOD.ENDCLASS.Vorteile:
- ✅ Vollständige Entkopplung
- ✅ Eigener Release-Zyklus
- ✅ Skalierung unabhängig von S/4HANA
- ✅ Beliebige Programmiersprachen (ABAP, Java, Node.js…)
Nachteile:
- ⚠️ Netzwerk-Latenz (API-Aufrufe)
- ⚠️ Höhere Komplexität (zwei Systeme)
- ⚠️ Zusätzliche Lizenzkosten (BTP)
Tier 2: Key User Extensibility (No-Code/Low-Code)
Prinzip: Fachanwender erweitern S/4HANA ohne Code über Tools
Custom Fields (Zusatzfelder):
SAP GUI → Einstellungen → Custom Fields and Logic1. Objekt wählen (z.B. Sales Order)2. "Neues Feld erstellen"3. Feldname: ZZ_PRIORITY4. Datentyp: String(10)5. Auf UI hinzufügen→ Fertig! Feld ist in Tabelle, CDS Views und UI verfügbarCustom Logic (Business Rules):
1. Trigger wählen: "Before Save - Sales Order"2. Bedingung: IF NetAmount > 100003. Aktion: SET ZZ_PRIORITY = 'HIGH'→ Keine ABAP-Kenntnis nötig!Vorteile:
- ✅ Schnell (Minuten statt Tage)
- ✅ Keine Entwickler-Skills nötig
- ✅ In S/4HANA integriert (keine Latenz)
- ✅ Automatisch upgrade-sicher
Nachteile:
- ⚠️ Limitierte Komplexität
- ⚠️ Nur für freigegebene Business Objects
Tier 3: Developer Extensibility (In-Stack)
Prinzip: ABAP-Entwicklung innerhalb von S/4HANA mit ABAP Cloud
Dies ist der Sweet Spot für klassische ABAP-Entwickler:
" ✅ GUT: ABAP Cloud Extension in S/4HANA" Nur freigegebene APIs nutzenCLASS zcl_sales_validator DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES if_badi_interface.ENDCLASS.
CLASS zcl_sales_validator IMPLEMENTATION. METHOD if_badi_interface~validate. " Zugriff NUR über Released APIs SELECT SINGLE * FROM i_salesorder " ← Released CDS View (von SAP freigegeben) WHERE salesorder = @iv_order_id INTO @DATA(ls_order).
" Geschäftslogik IF ls_order-TotalNetAmount > 50000. " Nachricht via Released API DATA(lo_msg) = cl_message_helper=>get_instance( ). " ← Released lo_msg->add_message( id = 'ZMSG' number = '001' v1 = 'Genehmigung erforderlich' ). ENDIF. ENDMETHOD.ENDCLASS.Wie erkenne ich Released APIs?
" In Eclipse ADT:" 1. API öffnen (z.B. CDS View, Klasse)" 2. Properties anzeigen → "API State"" 3. Suchen nach "Released" oder "C1" (Cloud-Ready)
" Beispiel: I_SalesOrder@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Sales Order'@Metadata.allowExtensions: true@ObjectModel.usageType.serviceQuality: #A@VDM.viewType: #BASIC
" → Wenn @VDM.viewType vorhanden: Teil des Virtual Data Model (VDM)" = Released für Consumption!
define view I_SalesOrder as select from vbak " ← vbak ist NICHT released, aber I_SalesOrder schon!{ key vbeln as SalesOrder, erdat as CreationDate, netwr as TotalNetAmount, waerk as TransactionCurrency}Released APIs finden:
SAP API Business Hub: api.sap.com
Filter: "API Type" → "ABAP Cloud" "Product" → "SAP S/4HANA"
Beispiele:- I_SalesOrder, I_Customer, I_Product (CDS Views)- CL_BALI_LOG (Application Logging)- CL_NUMBERRANGE_RUNTIME (Number Ranges)- CL_WEB_HTTP_* (HTTP Client)Clean Core Implementierungs-Strategie
Phase 1: Assessment (Ist-Analyse)
Custom Code Analyzer nutzen:
" Transaktion: ATC (ABAP Test Cockpit)" Oder in Eclipse ADT:" Projekt → Properties → ABAP Development → Code Inspector
" Check Variant: S4HANA_READINESS_REMOTE" → Zeigt alle Verwendungen nicht-freigegebener APIsTypische Findings:
| Kategorie | Beispiel | Risiko | Aufwand |
|---|---|---|---|
| Nicht-freigegebene Tabellen | SELECT FROM but000 | Hoch | Mittel |
| Implizite Enhancements | ENHANCEMENT-POINT | Hoch | Hoch |
| Nicht-released APIs | CALL FUNCTION 'RFC_READ_TABLE' | Mittel | Niedrig |
| DB-Direkt-Zugriff | OPEN CURSOR FOR SELECT * FROM (lv_tabname) | Sehr hoch | Hoch |
Phase 2: Bereinigung (Remediation)
Strategie 1: APIs ersetzen
" ❌ Vorher: Nicht-releasedSELECT SINGLE * FROM but000 WHERE partner = @lv_partner.
" ✅ Nachher: Released APISELECT SINGLE * FROM i_businesspartner WHERE businesspartner = @lv_partner INTO @DATA(ls_bp).Strategie 2: Wrapper-Layer
" Zentraler Wrapper für kritische ZugriffeCLASS zcl_bp_access DEFINITION PUBLIC CREATE PRIVATE. PUBLIC SECTION. CLASS-METHODS: get_instance RETURNING VALUE(ro_instance) TYPE REF TO zcl_bp_access,
get_business_partner IMPORTING iv_partner TYPE bu_partner RETURNING VALUE(rs_partner) TYPE i_businesspartner.
PRIVATE SECTION. CLASS-DATA go_instance TYPE REF TO zcl_bp_access.ENDCLASS.
CLASS zcl_bp_access IMPLEMENTATION. METHOD get_instance. IF go_instance IS NOT BOUND. CREATE OBJECT go_instance. ENDIF. ro_instance = go_instance. ENDMETHOD.
METHOD get_business_partner. " Heute: Released API SELECT SINGLE * FROM i_businesspartner WHERE businesspartner = @iv_partner INTO @rs_partner.
" Falls API nicht ausreicht: " TODO: SAP um API-Erweiterung bitten (über Influence Request) ENDMETHOD.ENDCLASS.
" In Custom-Code überall:DATA(ls_bp) = zcl_bp_access=>get_instance( )->get_business_partner( lv_partner )." → Wenn SAP API ändert: nur zcl_bp_access anpassen, nicht 100 StellenStrategie 3: Refactoring zu RAP
" ❌ Vorher: Dynpro-Programm mit DB-DirektzugriffREPORT zsales_order_maintain.
PARAMETERS: p_order TYPE vbeln.
START-OF-SELECTION. " Direkte Tabellenzugriffe UPDATE vbak SET status = 'CLOSED' WHERE vbeln = p_order. COMMIT WORK.
" ✅ Nachher: RAP Business Object" → siehe /rap-basics/ für DetailsMODIFY ENTITIES OF i_salesordertp ENTITY SalesOrder UPDATE FIELDS ( OverallSDProcessStatus ) WITH VALUE #( ( SalesOrder = lv_order OverallSDProcessStatus = 'C' ) ) FAILED DATA(failed) REPORTED DATA(reported).
COMMIT ENTITIES.Phase 3: Governance (Nachhaltig Clean bleiben)
1. ATC Checks in CI/CD Pipeline
# Azure DevOps / Jenkins Pipeline- task: ABAP_ATC_Check inputs: checkVariant: 'CUSTOM_CLOUD_READINESS' failOnErrors: true excludePackages: '$TMP' # Testentwicklungen ausschließen2. Development Guidelines dokumentieren
# ABAP Development Standards (Beispiel)
## Pflicht-Regeln1. ✅ Nur Released APIs (Check: API Business Hub)2. ✅ ABAP Cloud Syntax (kein CALL TRANSACTION, etc.)3. ✅ RAP für transaktionale Apps (kein Dynpro)4. ✅ CDS Views statt SELECT auf DB-Tabellen5. ✅ Kein Implicit Enhancement Framework
## Empfehlungen- Wrapper-Klassen für häufig genutzte APIs- Unit Tests mit Test Doubles (siehe /test-doubles-mocking/)- EML für BO-Zugriff (siehe /eml-guide/)3. Code Reviews mit Checkliste
Pull Request Checklist:□ ATC-Check grün (Clean Core Variant)?□ Nur Released APIs verwendet?□ Unit Tests vorhanden (Coverage ≥ 80%)?□ CDS Views dokumentiert (Labels/Descriptions)?□ Keine Implicit Enhancements?Clean Core & ABAP Cloud
ABAP Cloud = technische Umsetzung von Clean Core
" ABAP Cloud Language Version: Compiler erzwingt Clean Core!
CLASS zcl_order_processor DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES if_oo_adt_classrun.ENDCLASS.
CLASS zcl_order_processor IMPLEMENTATION. METHOD if_oo_adt_classrun~main. " ✅ Erlaubt: Released API SELECT * FROM i_salesorder INTO TABLE @DATA(lt_orders).
" ❌ Compiler-Fehler: vbak ist nicht released! " SELECT * FROM vbak INTO TABLE @DATA(lt_vbak). " → "vbak is not released for ABAP Cloud"
" ❌ Compiler-Fehler: CALL TRANSACTION nicht erlaubt " CALL TRANSACTION 'VA03'. " → "CALL TRANSACTION is not allowed in ABAP Cloud" ENDMETHOD.ENDCLASS.ABAP Cloud aktivieren in S/4HANA:
Eclipse ADT:1. Package erstellen/öffnen2. Properties → ABAP Language Version3. Auswählen: "ABAP for Cloud Development"→ Alle Objekte in diesem Package sind Clean Core-konform!Migration: Schritt für Schritt
Beispiel: Sales Order Enhancement
Ausgangssituation (Classic ABAP):
" ❌ User-Exit in SAP Standard eingebautENHANCEMENT-SECTION zenhancement_vbap IN sapmv45a. ENHANCEMENT 1 zorder_validation. " Zugriff auf globale Variablen des SAP-Programms IF vbap-matnr CO '0123456789'. MESSAGE 'Ungültige Materialnummer' TYPE 'E'. ENDIF. ENDENHANCEMENT.END-ENHANCEMENT-SECTION.Migration zu Clean Core (ABAP Cloud + RAP):
" ✅ Schritt 1: BAdI nutzen (falls vorhanden)CLASS zcl_order_badi DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES if_ex_sd_sales_item_check. " ← SAP-BAdIENDCLASS.
CLASS zcl_order_badi IMPLEMENTATION. METHOD if_ex_sd_sales_item_check~validate_item. " Zugriff nur über Interface-Parameter (kein Global Access) IF is_item-material CO '0123456789'. " Released API für Messages DATA(lo_msg) = cl_bali_message_setter=>create( severity = if_bali_constants=>c_severity_error id = 'ZMSG' number = '001' ). APPEND lo_msg TO ct_messages. ENDIF. ENDMETHOD.ENDCLASS.
" ✅ Schritt 2: Falls kein BAdI → Wrapper Event" Siehe RAP Business Events: /events-raise-handler/
" ✅ Schritt 3: Langfristig → RAP Validation" In Behavior Definition:validation validateMaterialNumber on save { field Material; }
" Behavior Implementation:METHOD validateMaterialNumber. READ ENTITIES OF zi_salesorder IN LOCAL MODE ENTITY SalesOrderItem FIELDS ( Material ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_items).
LOOP AT lt_items INTO DATA(ls_item) WHERE Material CO '0123456789'. APPEND VALUE #( %tky = ls_item-%tky %element-Material = if_abap_behv=>mk-on ) TO failed-salesorderitem.
APPEND VALUE #( %tky = ls_item-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Ungültige Materialnummer' ) ) TO reported-salesorderitem. ENDLOOP.ENDMETHOD.Tools für Clean Core
| Tool | Zweck | Transaktion/Link |
|---|---|---|
| Custom Code Migration App | Analyse + Tracking | Fiori Launchpad: F2802 |
| ATC (ABAP Test Cockpit) | Statische Code-Prüfung | SE80/ADT |
| SAP API Business Hub | Released APIs finden | api.sap.com |
| ABAP Cloud Flight Checker | Clean Core Violations | Eclipse ADT |
| Code Inspector | Legacy-Prüfungen | SCI/ATC |
| Transport Dependency Analyzer | Impact-Analyse | SE03 |
Wichtige Hinweise / Best Practice
- Clean Core ist keine Option: Ab S/4HANA 2025+ wird es Pflicht für Cloud-Editionen
- Früh starten: Migration dauert 2-5 Jahre je nach Custom-Code-Umfang
- 80/20-Regel: 20% des Codes verursachen 80% der Probleme – priorisieren Sie!
- SAP Influence nutzen: Fehlt eine Released API? → influence.sap.com
- Nicht alles migrieren: Alte, selten genutzte Programme ggf. stilllegen
- Wrapper-Pattern: Kapseln Sie Übergangscode in zentralen Klassen
- ABAP Cloud = Compiler-Unterstützung: Nutzen Sie die Language Version für neue Entwicklungen
- Test Doubles: Siehe Test Doubles & Mocking für Clean Testing
- RAP-First: Neue transaktionale Apps immer mit RAP (siehe RAP Basics)
- Dokumentation: Jede Abweichung begründen (z.B. “SAP liefert API erst in Release XY”)
- Governance etablieren: Pull Requests + ATC-Checks = dauerhaft Clean Core
- Training: Team schulen – Clean Core ist Mindset-Change, nicht nur Syntax
Weitere Ressourcen
- ABAP Cloud: /abap-cloud-definition/
- RAP Grundlagen: /rap-basics/
- Migration Guide: /migration-classic-to-cloud/