Skip to Content
Technical Articles

Calling a BAPI in the SAP S/4HANA Cloud from a non-SAP system

Introduction

In the previous blog post of this series we saw how to call a whitelisted BAPI in the SAP S/4HANA Cloud using SAP Process Orchestration. Now we are going to take a look how we can do the same from a non-SAP application.

Calling a BAPI in the Cloud from non-SAP systems ( e.g. a JAVA program)

Non-SAP systems can make RFC-Calls to the S/4HANA Cloud as long as they adhere to the RFC standards. That is usually done by implementing the libraries which were published by SAP. There are numerous solutions available which implement the RFC protocol this way and are certified. These 3rd party products usually come along with a guide which explains how to integrate with SAP systems. For SAP On-Premise solutions it has been like this for many years. For the SAP S/4HANA Cloud it works as well (as we will see) but there are some official restrictions:

Please keep SAP Note 2447593 in mind which is saying that RFC should only be used to integrate S/4 HANA Cloud with SAP OnPremise-Solutions (and be it, that it is SAP PO). So whatever you do with non-SAP systems, RFC/BAPI and the SAP S/4HANA Cloud is at your own risk.

Preparation

What I used

  • A functional SAP Cloud Connector Instance + user with administrative privileges
  • An SAP S/4 HANA Public Cloud Tenant + user with administrative privileges
  • Eclipse
  • SAP JCO libraries

What I did

  • Download the JCO libraries
  • Import the JCO libraries into Eclipse
  • Set up the JCO Destination File
  • Test the connection and the BAPI call with the sample programs

Setting up Eclipse

One way of simulating a non-SAP System is making use of a SAP Connector, the JCO libraries. You can find them here: SAP Java Connector. In my example I set up an Eclipse Project and implemented a program that was based on the samples provided with the JCO library. I had to play around a little bit but in the end it worked.

Being not much of a Java guy, I was inspired by 2 Blogs from varun boyina which helped me to set up the example.

Initially I wanted to go via the good old RFC libraries which were used to be delivered with the SAP GUI and included such useful programs like startrfc.exe but that isn’t the case anymore. You can still download a NW RFC library if you want to (see here) but startrfc doesn’t work the way I thought it did anymore or maybe I’m mixing things up and don’t remember it properly. The last time I actually used startrfc was about 15 years ago. Programs change, memories fade…

Eclipse and the JCO worked fine for me and anybody who is more familiar with Eclipse and Java should get along easily.The project structure in Eclipse looks like this:

 

JCO Destination File

You can either put the destination details into the program or put an RFC destination file into the project. This file contains the information to establish a connection:

#for tests only !
#Tue May 15 16:51:44 CET 2019
jco.client.lang=EN
jco.client.client=100
jco.client.passwd= <Put the password of the S4HC API User of the CommScenario here>
jco.client.user=<Put the name of the S4HC API User of the CommScenario here>
jco.client.sysnr=00
jco.client.ashost=<Adress of the SCC, e.g. xxx.mo.sap.corp>

In the example the file is called “SCC_PRACTICE.jcoDestination”. You can see it in the project structure above. You need to put your own destination details for passwd, user and ashost.

Sample Program

With the program below I was able to read equipment data from the S/4 HANA Cloud. It is a very basic program and not dynamic at all. But it shows that actually not much is required to do the calls. If you want to get into the details I recommend that you read the documentation: SAP Java Connector (Standalone Version).

package jne;



import com.sap.conn.jco.AbapException;
//	import com.sap.conn.jco.JCoContext;
	import com.sap.conn.jco.JCoDestination;
	import com.sap.conn.jco.JCoDestinationManager;
	import com.sap.conn.jco.JCoException;
//	import com.sap.conn.jco.JCoField;
	import com.sap.conn.jco.JCoFunction;
//	import com.sap.conn.jco.JCoFunctionTemplate;
	import com.sap.conn.jco.JCoStructure;
//	import com.sap.conn.jco.JCoTable;
//  import com.sap.conn.jco.ext.DestinationDataProvider;

	/**
	 * basic examples for Java to ABAP communication  
	 */
	public class RFCBAPI
	{
//		static String SCC = "SCC_JNE";
		static String SCC = "SCC_PRACTICE";
		
	      	  	    
	    /**
	     * This example demonstrates the destination concept introduced with JCO 3.
	     * The application does not deal with single connections anymore. Instead
	     * it works with logical destinations like ABAP_AS and ABAP_MS which separates
	     * the application logic from technical configuration.     
	     * @throws JCoException
	     */
	    public static void step1Connect() throws JCoException
	    {
	        JCoDestination destination = JCoDestinationManager.getDestination(SCC);
	        System.out.println("Attributes:");
	        System.out.println(destination.getAttributes());
	        System.out.println();


	    }
	    
	   
	    public static void step5CallBAPI() throws JCoException
	    {
	       	System.out.println("Initiating");
			JCoDestination destination = JCoDestinationManager.getDestination(SCC);
			System.out.println("Calling:");
			JCoFunction function = destination.getRepository().getFunction("BAPI_EQUI_GETDETAIL");
			if(function == null)
				throw new RuntimeException("BAPI_EQUI_GETDETAIL not found in SAP.");
				try
					{
						function.getImportParameterList().setValue("EQUIPMENT", "000000000010000000");
						function.execute(destination);
					}
				catch(AbapException e)
					{
					System.out.println("ABAP Exception");	
					System.out.println(e.toString());
					}
				try
					{
					System.out.println("BAPI_EQUI_GETDETAIL finished:");
//					System.out.println(function.toXML());
 					printStruct(function,"DATA_GENERAL_EXP");
//					printStruct(function,"DATA_SPECIFIC_EXP");
//					printStruct(function,"DATA_FLEET_EXP");
//					printStruct(function,"RETURN");
				  					}
				catch(Exception e)
					{
						e.printStackTrace();
					}
	    }

	    
	    public static void step6PrintBAPI() throws JCoException
	    {
	       	System.out.println("Initiating:");
			JCoDestination destination = JCoDestinationManager.getDestination(SCC);
			System.out.println("Calling:");
			JCoFunction function = destination.getRepository().getFunction("BAPI_EQUI_GETDETAIL");
			if(function == null)
				throw new RuntimeException("BAPI_EQUI_GETDETAIL not found in SAP.");
				try
					{
						function.getImportParameterList().setValue("EQUIPMENT", "000000000010000000");
//						function.getImportParameterList().setValue("REQUEST_INSTALLATION_DATA", "X");
						function.execute(destination);
					}
				catch(AbapException e)
					{
					System.out.println("ABAP Exception");	
					System.out.println(e.toString());
					}
				try
					{
					System.out.println("BAPI_EQUI_GETDETAIL finished:");
					System.out.println(function.toXML());
//					System.out.println(function.getFunctionTemplate());
// 					printStruct(function,"DATA_GENERAL_EXP");
//					printStruct(function,"DATA_SPECIFIC_EXP");
//					printStruct(function,"DATA_FLEET_EXP");
//					printStruct(function,"RETURN");
				  					}
				catch(Exception e)
					{
						e.printStackTrace();
					}
	    }
	    
	    public static void printStruct(JCoFunction BAPI, String StrucName) {
	    	
	    	System.out.println("\n" + "Structure: " + StrucName);
	    	JCoStructure BAPIStruc = BAPI.getExportParameterList().getStructure(StrucName);
	    	for (int i = 0; i < BAPIStruc.getFieldCount(); i++)
	        {
            	System.out.println(i + ": " + BAPIStruc.getString(i));;
	        }	
	    }
	    
	    
	    public static void main(String[] args) throws JCoException
	    {
//			Set Destination	 

//	    	step0DestinationFile();
	        step1Connect();
//          step2ConnectUsingPool();
//	        step3SimpleCall();
//	        step4WorkWithTable();
//	        step4SimpleStatefulCalls();
//            step5CallBAPI();
            step6PrintBAPI();
	    }
	}

Conclusion

What I learned from this test case

With this test case I brushed up my Java a little bit. For somebody who has used the JCO libraries already in the OnPrem world there is nothing new. The implementation is the same, just the RFC Destination is pointing to the SAP Cloud Connector.

Your Feedback

Please let me know if the description was helpful and you were able to set up the same test case. Any feedback how to improve this blog post is welcomed! Please put it in the comment section.

What’s next

Next time I will show you how to call a BAPI on-premise from SAP Cloud Platform Integration. It’s also the preparation for the final test case in which I do a call from the Cloud and back. Check back soon!

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.