SAP Java Connector SAPJCO3

I am posting this here and hope it helps someone (and myself in the future), as I could not find a working example of code for Domino when I was looking.

My java skill is not great so if there is a better way to do something let us know.

My Scenario:

What I wanted to do was to use the SAP JCO3 connector to retrieve info from a BAPI based on parameters submitted. We use the SAP Connector in LotusScript but because of reporting I needed to use java. Using LS2J created problems with the data so I re wrote it complete in java to overcome the LS2J limitations.

The code gets the connection parameters from a profile document. I used an agent and a library for in this scenario.

Please note that the sapjco3.jar file must be added to the ext folder on the Domino server and I added the sapjco3.dll to the program folder of the Domino server. In my code I added the sapjco3.jar to my library but this should not be necessary with the jar in the ext folder on the server.

My code:

AGENT:

import lotus.domino.*;

public class JavaAgent extends AgentBase {

public void NotesMain() {

try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();

// (Your code goes here)
System.out.println(“Start”);

Database db = agentContext.getCurrentDatabase();
Document docConnect = db.getProfileDocument(“(Connections)”,“”);

//SAPConnect mySAP=new SAPConnect();
SAPConnect.sapConnect(docConnect); //Connect
SAPConnect.sapData(); //Get the data

} catch(Exception e) {
e.printStackTrace();
}
}
}

LIBRARY

import lotus.domino.*;

import java.util.*;

import com.sap.conn.jco.AbapException;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoRepository;
import com.sap.conn.jco.JCoTable;
import com.sap.conn.jco.ext.DestinationDataProvider;

public class SAPConnect {

static String ABAP_AS = “ABAP_AS_WITHOUT_POOL”;
static String ABAP_AS_POOLED = “ABAP_AS_WITH_POOL”;
static String ABAP_MS = “ABAP_MS_WITHOUT_POOL”;

private static JCoDestination destination=null; //Connection name
private static String tName = “BAPI_NAME”; //BAPI Name
private static String dataTable=“RETUNEDTABLENAME”; //Returned Data Table Name

static
{

/*
System.out.println(“Started connectProperties”);

Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, “xxx”);
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, “xxx”);
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, “xxx”);
connectProperties.setProperty(DestinationDataProvider.JCO_USER, “xxx”);
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, “xxx”);
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, “en”);

//These are only used if using Pool Connection
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, “3”);
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, “10”);

//createDataFile(ABAP_AS_POOLED, “JCoDestination”, connectProperties);

System.out.println(“connectProperties End”);
*/
}

public static void sapConnect(Document docConn) throws JCoException
{

System.out.println(“sapConnect Start”);

Properties connectProperties = new Properties();

if (docConn!=null){
try {
System.out.println(“docConn NOT null”);
//Set values according to what is in the profile document
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, docConn.getItemValueString(“txtSAP_Server”));
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, docConn.getItemValueString(“txtSAP_SystemNo”));
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, docConn.getItemValueString(“txtSAP_Client”));
connectProperties.setProperty(DestinationDataProvider.JCO_USER, docConn.getItemValueString(“txtSAP_UserID”));
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, docConn.getItemValueString(“txtSAP_Password”));
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, docConn.getItemValueString(“txtSAP_Language”));

//These are only used if using Pool Connection
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, “3”);
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, “10”);

} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
//System.out.println(“Attributes:”);
//System.out.println(destination.getAttributes());
//System.out.println();
//destination.ping();

System.out.println(“sapConnect End”);
}

public static void sapData() throws JCoException{

System.out.println(“sapData Start”);
String key=null;
String value=null;

//Setting parameters for getting data
Map mapA = new HashMap();
mapA.put(“FIELDNAME1”, “0123456”);
mapA.put(“FIELDNAME2”, “L012345”);

//Set the repository
//System.out.println(“getData 2”);
JCoRepository mRepository;
mRepository = destination.getRepository ();

JCoFunction function = mRepository.getFunction(tName);

if (function == null)
throw new RuntimeException(tName + " not found in SAP.");
try
{
//Loop through parameter values and set them
System.out.println(“getData 4”);
Iterator iterator = mapA.keySet().iterator();
while(iterator.hasNext()){
key = (String) iterator.next();
value = (String) mapA.get(key);

function.getImportParameterList().setValue(key, value);

}

//Execute to get data
function.execute(destination);

}
catch(AbapException e)
{
System.out.println(e.toString());
return;
}

// System.out.println(function);

//Set Table with data
JCoTable jcoTabled = function.getTableParameterList().getTable(dataTable);

//Check number of rows returned
int numRows = jcoTabled.getNumRows();
System.out.println("numRows > " + numRows);

if (numRows > 0) {

for (int i = 0; i < numRows; i++)
{

//Get the data
System.out.println("Row > " + i);
jcoTabled.setRow(i);

//System.out.println(jcoTabled.getRecordMetaData()); //Meta Data

System.out.println(jcoTabled.getValue(“TABLECOLNAME1”)); //Print column value
System.out.println(jcoTabled.getValue(“TABLECOLNAME2”)); //Print column value
System.out.println(jcoTabled.getValue(“TABLECOLNAME3”)); //Print column value

}

}

System.out.println(“sapData End”);
}

}

Subject: NoClassDefFoundError exception

Hi I get this error,

I have the jar and so for zSeries copied in domino_instalation/jvm/lib/ext and in domino_instalation folder.

The server was restarted and I know at least the so file is loaded since I used static { System.load(“libsapjco3.so”); } and I get a link exception since another classloader loaded it.

12/06/2015 19:50:10 Agent error: Exception in thread “AgentThread: JavaAgent”
12/06/2015 19:50:10 Agent error: java.lang.NoClassDefFoundError: com.sap.conn.jco.JCo (initialization failure)
12/06/2015 19:50:10 Agent error: at java.lang.J9VMInternals.initialize(J9VMInternals.java:139)
12/06/2015 19:50:10 Agent error: at com.sap.conn.jco.JCoDestinationManager.getDestination(JCoDestinationManager.java:77)
12/06/2015 19:50:10 Agent error: at JavaAgent.step1Connect(JavaAgent.java:51)
12/06/2015 19:50:10 Agent error: at JavaAgent.NotesMain(JavaAgent.java:41)
12/06/2015 19:50:10 Agent error: at lotus.domino.AgentBase.runNotes(Unknown Source)
12/06/2015 19:50:10 Agent error: at lotus.domino.NotesThread.run(Unknown Source)

Can you help me?

Subject: NoClassDefFoundError exception

I normally import the jar into the library or agent as it helps with admin keeping the file updated on server unless there are performance issues. Have you tried doing it this way?

Subject: SAP Java Connector SAPJCO3 - Update

We recently moved our SAP to unicode and onto Linux. After the conversion and move to different IP address we had an issue where the new IP was not been set by the SAP JCO. After sometime we found a solution to the problem which is a better way to do the connection, hence a change to the original code I posted.

The original code has lines like this setting the properties -

Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, “xxx”);

The problem is that the SAP JCO seems to create a property file on the file system which is initially set and then thereafter always read and not updated with any new values. To over come this problem the connection was changed to this -

public static void sapConnect(Document docConn) throws JCoException

{

System.out.println(“sapConnect Start”);

Properties connectProperties = new Properties();

if (docConn!=null){

try {

//Set values according to what is in the profile document

connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, docConn.getItemValueString(“txtSAP_Server”));

connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, docConn.getItemValueString(“txtSAP_SystemNo”));

connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, docConn.getItemValueString(“txtSAP_Client”));

connectProperties.setProperty(DestinationDataProvider.JCO_USER, docConn.getItemValueString(“txtSAP_UserID”));

connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, docConn.getItemValueString(“txtSAP_Password”));

connectProperties.setProperty(DestinationDataProvider.JCO_LANG, docConn.getItemValueString(“txtSAP_Language”));

connectProperties.setProperty(DestinationDataProvider.JCO_CODEPAGE,“4103”);

createDestinationDataFile(ABAP_AS, connectProperties);

//These are only used if using Pool Connection

connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, “3”);

connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, “10”);

} catch (NotesException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

destination = JCoDestinationManager.getDestination(ABAP_AS);

JCoAttributes attributes = destination.getAttributes();

System.out.println(“Connection attributes:\n” +

“--------Connection attributes------\n” + attributes);

boolean is_backend_unicode = attributes.getPartnerCodepage().equals(“4102”) ||

attributes.getPartnerCodepage().equals(“4103”);

System.out.println(“trace:\n” +

“--------Connection attributes-----\n” + attributes.getTrace());

System.out.println(“sapConnect End”);

}

/*

  • Create the properties file for connection

*/

static void createDestinationDataFile(String destinationName, Properties connectProperties)

{

File destCfg = new File(destinationName+“.jcoDestination”);

try

{

FileOutputStream fos = new FileOutputStream(destCfg, false);

connectProperties.store(fos, “SAP JCo with Domino”);

fos.close();

}

catch (Exception e)

{

throw new RuntimeException(“Unable to create the destination files”, e);

}

}

The (createDestinationDataFile) is where the file is created on the file system and the values always updated.

I hope this helps anyone out there.