Connecting to SAP with 3rd party Python lib or SAP JCo jar

we followed all the above steps what you suggested. Please find the details below:

  1. we downloaded SAPJco3.jar file and mapped the path into ignition.conf file.

Java Classpath (include wrapper.jar) Add class path elements as# needed starting from 1

wrapper.java.classpath.1=lib/wrapper.jar
wrapper.java.classpath.2=lib/core/common/*
wrapper.java.classpath.3=lib/core/gateway/*

Java Classpath for Interface for SAP ERP

wrapper.java.classpath.4=C:\Program Files/InductiveAutomation/Ignition/user-lib/jco/sapjco3.jar
#wrapper.java.classpath.4=lib/sapjco3.jar
#wrapper.java.classpath.4=C:\Program Files/Inductive Automation/Ignition/lib/sapjco3.jar

path for Link Ignition site-packages with jpython site-packages

wrapper.java.classpath.5=lib/jython.jar
....................................................................................................................
2. we created DEV.jcoDestination file and kept in Ignition folder and we added below details.

ashost='XXX.corp.timken.com' #147.185.XX.XX
sysnr='01'
client=100
user='XYZ'
passwd='*****'
lang='en'
pool_capacity=0
..............................................................................................................
3. we are writing python script to call BAPI in Script Console in Ignition. But getting error. Please find below code and attached error image.

sapSystem='DEV'
from com.sap.conn.jco import *
#from com.sap.conn.jco import JCoDestinationManager
destination = JCoDestinationManager.getDestination(sapSystem)

Error

Java Traceback:
Traceback (most recent call last):
File "", line 4, in
at com.sap.conn.jco.JCoDestinationManager.getDestination(JCoDestinationManager.java:56)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
java.lang.NoClassDefFoundError: java.lang.NoClassDefFoundError: Could not initialize class com.sap.conn.jco.JCo


...........................................................

Please guide us after this. It will be very helpful for continuing with Ignition Software.

EDIT: We are able to read DEV.jcoDestination file, but when we are trying to ping it's giving "No User identity is configured" Error.
Currently I have installed SAPJco3 jar and Ignition in my local system and I have access of SAP GUI. I have mapped same credentials and other SAP details in DEV.jcoDestination, I have also created one Technical User to call BAPI, but from both User, we are getting same error, Please help

This is your problem. The Designer Script console does not run your script in the gateway process. You need to put your SAP code into a gateway message handler, or better, in a script module called from a message handler. In the designer's script console, use system.util.sendRequest() to cause your code to run in the gateway process. (And retrieve any return value.)

Gateway Event Scripts - Ignition User Manual 8.1 - Ignition Documentation (inductiveautomation.com)

I found information on the message handler here.
I am looking forward to learning more about connecting to SAP @kavya_shree

I honestly build a ship in a bottle, where the designer is the bottle.

I think there is enough here for some people to implement SAP in Ignition.

I appreciate help to make this a little more accessible for me.

I am in Ignition 8.1. Is this outdated?

Could someone make a guide with more accessibility?
Or, I can kind of ask questions to get some help alternatively:

  1. phyatt said Place the SAPJco3 library in a folder on your gateway.
    (c:\SAPJco3 for example)
    get the bit version to match your Java environment. (i.e.: 64 bit SAPJco3 library)
    1a. The "gateway" is a primary software service that runs as a web server.
    1b. The file just has to be in a drive on the computer that the software is running on, yes?

  2. edit Ignition.conf file and add wrapper.java.classpath.3=c:\SAPJco3/sapjco3.jar
    2a. Ignition.conf is a file on the gateway, and can be edited with notepad++ yes?
    2b. Add wrapper.java.classpath.3=c:\SAPJco3/sapjco3.jar anywhere in the file?
    2c. No indent, yes?
    2d. This tells our gateway where the files is on the gateway, yes?

  3. I need to add three lines, not one, yes?
    3a. I increment the path number and write my one line at the
    bottom for the location of the file?

# Java Classpath (include wrapper.jar)  Add class path elements as
#  needed starting from 1
wrapper.java.classpath.1=lib/wrapper.jar
wrapper.java.classpath.2=lib/catapult.jar
wrapper.java.classpath.3=c:\SAPJco3/sapjco3.jar 
  1. Place required .jcoDestination files in the \Program Files\Inductive Automation\Ignition folder.
    4a. This is a file that comes in the SAP Jco3 software, yes?
    4b. How do I know it is safe? Is that from SAP?
    4c. what are the three files for?
    4d. Dev, QAS, and PRD related to subsections SAP that SAP users are familiar with?

  2. lib/wrapper.jar and lib/catapult.jar are a shorthand notation, I actually need what?

  3. Place this script in the designer in Scripting>project library>new script ?
    This part was a bit confusing to me and I need to know a lot more about it.

ashost=192.168.x.x
sysnr=00
client=110
user=username
passwd=password  (The SAPJco3 library will update a clear text password with an encrypted version after the first connection.)
lang=en
pool_capacity=0
  1. Then I also can create my functions in that script.
    This part is confusing to me, and I think I need to know a lot more about it.

I think I understand that SAP has datasets in it, and I can make functions to return those datasets.
"Z_OEE_RATE_LIST" is a reference to a hypothetical custom table that SAP power users created for the example?
So I would talk to my company SAP power users to know the names of the tables?
SAP has a single location for tables that I could return as datasets?


Are Kavya and phyatt talking about the same thing?
Or is phyatt writing custom functions, and Kavya is using part of the connection method to then access BAPI that contains predefined functions?

I asked many questions.

I am still hoping for a simple solution to connect to SAP that is as simple as connecting to an MS SQL server if possible.
Ignition version 8.1.19.
I think I will be using SAP HANA soon.

I have a client that does exactly this. Their IT group built some stored procedures that call SAP's libraries from within the SQL Server. Ignition just calls those stored procedures in SQL Server.

1 Like

Hi Team,

I am calling BAPI in Ignition script console. I am able to fetch the table from SAP ECC but I am not getting its value.
please check for the below screen shots.
Below is the output table from ECC: fetching only Headers.

Below is the script in script console:

Below is my Actual data in SAP ECC, in xml format

Hi Team,

I have solved above issue.

Now I am able to call BAPI and fetching the details of Table from ECC. This code I am executing in Script console.

But same code I applied on Button, I am not getting same output. Getting below error.

com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 34, in runAction NameError: global name 'JCoDestinationManager' is not defined
at org.python.core.Py.NameError(Py.java:261)
at org.python.core.PyFrame.getglobal(PyFrame.java:265)
at org.python.pycode._pyx1.runAction$1(:75)
at org.python.pycode._pyx1.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
at org.python.core.PyFunction.function___call__(PyFunction.java:474)
at org.python.core.PyFunction.__call__(PyFunction.java:469)
at org.python.core.PyFunction.__call__(PyFunction.java:464)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:847)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:829)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:852)
at com.inductiveautomation.ignition.common.script.ScriptManager$ScriptFunctionImpl.invoke(ScriptManager.java:1010)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.invoke(ProjectScriptLifecycle.java:934)
at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:158)
at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:97)
at com.inductiveautomation.perspective.gateway.action.ScriptAction.runAction(ScriptAction.java:74)
at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.lambda$call$0(ActionCollection.java:263)
at com.inductiveautomation.perspective.gateway.api.LoggingContext.mdc(LoggingContext.java:54)
at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:252)
at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:221)
at com.inductiveautomation.perspective.gateway.threading.BlockingTaskQueue$TaskWrapper.run(BlockingTaskQueue.java:154)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: NameError: global name 'JCoDestinationManager' is not defined
... 28 common frames omitted

please guide

Show your code. (All relevant parts.)

Hi,
I applied this script on button action event, in script console its working but same on action button its giving an error.

def runAction(self, event):
		import com.sap.conn.jco
		import com.sap.conn.jco.ext as et
		import java.util as ut
		import java.io as fil
		import java.lang.Object as obj
		import java.io.OutputStream as filOut
		import java.io.FileOutputStream as filOutput
		from com.sap.conn.jco import *
		import os
		import getpass
		directory = os.getcwd()
		user = getpass.getuser()
		system.perspective.print(directory)
		system.perspective.print(user)
		target = "C:\\Program Files\\Inductive Automation\\Ignition\\DEV";
		connectProperties = ut.Properties();
		connectProperties.setProperty(et.DestinationDataProvider.JCO_ASHOST, "");
		connectProperties.setProperty(et.DestinationDataProvider.JCO_SYSNR,  "" );
		connectProperties.setProperty(et.DestinationDataProvider.JCO_CLIENT, "");
		connectProperties.setProperty(et.DestinationDataProvider.JCO_USER,   "");
		connectProperties.setProperty(et.DestinationDataProvider.JCO_PASSWD, "");
		connectProperties.setProperty(et.DestinationDataProvider.JCO_LANG,   "");     
		destCfg = fil.File(target + ".jcoDestination");
		system.perspective.print(destCfg)
		fos =  fil.FileOutputStream(destCfg, 0);
		connectProperties.store(fos, target);
		fos.close();
		destination = JCoDestinationManager.getDestination("DEV");
		system.perspective.print(destination)

ERROR : ---

com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 34, in runAction NameError: global name 'JCoDestinationManager' is not defined
at org.python.core.Py.NameError(Py.java:261)
at org.python.core.PyFrame.getglobal(PyFrame.java:265)
at org.python.pycode._pyx1.runAction$1(:75)
at org.python.pycode._pyx1.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
at org.python.core.PyFunction.function___call__(PyFunction.java:474)
at org.python.core.PyFunction.__call__(PyFunction.java:469)
at org.python.core.PyFunction.__call__(PyFunction.java:464)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:847)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:829)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:852)
at com.inductiveautomation.ignition.common.script.ScriptManager$ScriptFunctionImpl.invoke(ScriptManager.java:1010)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.invoke(ProjectScriptLifecycle.java:934)
at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:158)
at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:97)
at com.inductiveautomation.perspective.gateway.action.ScriptAction.runAction(ScriptAction.java:74)
at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.lambda$call$0(ActionCollection.java:263)
at com.inductiveautomation.perspective.gateway.api.LoggingContext.mdc(LoggingContext.java:54)
at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:252)
at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:221)
at com.inductiveautomation.perspective.gateway.threading.BlockingTaskQueue$TaskWrapper.run(BlockingTaskQueue.java:154)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: NameError: global name 'JCoDestinationManager' is not defined

Thank you

runAction implies that this button is in Perspective. If so, it is running in the gateway, not the designer (and will not run in a browser client's computer). You haven't set up your JARs and related settings to work in the gateway.

{ The designer script console's scope is similar to Vision scope, not to Perspective. Largely worthless for testing things you plan to use in Perspective. }

can you please guide how to set up JARs and related settings to work in the gateway.

Thank you

1 Like

Thanks a lot for your help! I followed these steps and it worked fine! Have a nice day =)