How to create users in SAP ERP with Java Jco3, part 1 – connecting to SAP ERP

TL;DR; I had to create dozens of users for students in SAP ERP. Remote SAP API comes to help. Few dozens of Java code lines that uses JCo (Java Connection Library) and I can create or delete SAP users in no time. This post is the first in the 3-post series. You can find source code on github.

We hate manual repeatable work. So we automatize. We automatize a lot. Since I started teaching the software development for SAP, I have found it every time surprising how powerful remote SAP ERP APIs is — SAP BAPI. With a decent library support, we can easily write ad-hoc programs to solve problems in hand. For example, when you need to create or delete dozens of users.

You can use the SAP BAPI to create a quick prototype or to automatize repeatable tasks.

First, you need to download JCO library. You can grab it from the SAP marketplace. If you are a student, ask your lecturer/trainer to get access to the java library.

Let’s start my beloved eclipse 😉 and create a Java project:


|-src
|-lib
\- gradle.build

What we need first, is our connection configuration (in next posts, we will see how to provide it with a properties file). We will use Properties to provide the connection configuration:

package pl.wbarczynski.sap.cli.CreateLogonUsers;

import java.util.Properties;

import com.sap.conn.jco.ext.DestinationDataEventListener;
import com.sap.conn.jco.ext.DestinationDataProvider;

class CreateLogonUsers {

  protected static Properties getRouterProperties() {
    final Properties cp = new Properties();
    
    /* conn=/H/saprouter.myhost/S/3297/H/I78z&user=wb&cInt=900 */

    cp.setProperty(DestinationDataProvider.JCO_MSHOST, "i78z");

    cp.setProperty(DestinationDataProvider.JCO_MSSERV, "3678");

    cp.setProperty(DestinationDataProvider.JCO_GROUP, "SPACE");
    cp.setProperty(DestinationDataProvider.JCO_CLIENT, "900");
    cp.setProperty(DestinationDataProvider.JCO_USER,   "wb");
    cp.setProperty(DestinationDataProvider.JCO_PASSWD, "wbsecretpass");
    cp.setProperty(DestinationDataProvider.JCO_SYSNR,  "1");
    cp.setProperty(DestinationDataProvider.JCO_LANG,   "en");
    cp.setProperty(DestinationDataProvider.JCO_SAPROUTER, "/H/saprouter.myhost/S/3297");

    return cp;
  }

  protected static Properties getDirectProperties() {
    Properties cp = new Properties();

    /* conn=/H/127.0.0.1/S/3300&cInt=800&user=wb */
    
    cp.setProperty(DestinationDataProvider.JCO_ASHOST, "/H/127.0.0.1/S/3300");
    cp.setProperty(DestinationDataProvider.JCO_CLIENT, "800");

    cp.setProperty(DestinationDataProvider.JCO_USER,   "wb" ); 

    cp.setProperty(DestinationDataProvider.JCO_PASSWD, "wbsecretpass" );
    cp.setProperty(DestinationDataProvider.JCO_SYSNR,  "1");
    cp.setProperty(DestinationDataProvider.JCO_LANG,   "en");
    return cp;
  }

  protected static Properties getJcoProperties() {
  	return getDirectProperties();
  }
  
  public static void main(String[] args) throws JCoException {
      
    Properties pp = getJcoProperties();
      
   }
}

Having properties, we need to register a DestinationDataProvider to get JCo to connect to our SAP ERP instance. Unfortunately, we cannot just provide the Properties to JCo. We need to wrap it with a helper class that implements DestinationDataProvider. Let's do it:


import java.util.Properties;

import com.sap.conn.jco.ext.DestinationDataEventListener;
import com.sap.conn.jco.ext.DestinationDataProvider;;

public class PropertiesDestinationDataProvider implements DestinationDataProvider {

	private Properties props;

	public PropertiesDestinationDataProvider(Properties props) {
		this.props = props;
	}
	
	@Override
	public Properties getDestinationProperties(String destinationName) {
		return this.props;
	}

	@Override
	public void setDestinationDataEventListener(
			DestinationDataEventListener arg0) {
		// nothing to do
		
	}

	@Override
	public boolean supportsEvents() {
		return false;
	}
}

Go back to CreateLogonUsers. Let's use the PropertiesDestinationDataProvider in our main class CreateLogonUsers and establish a connection to the SAP ERP:


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.JCoRepository;

import com.sap.conn.jco.ext.DestinationDataProvider;
import com.sap.conn.jco.ext.Environment;

import java.util.Date;
import java.util.Properties;

class CreateLogonUsers {

  public static JCoDestination getDestination() throws JCoException {
    return JCoDestinationManager.getDestination("whatever");
  }

  public static void main(String[] args) throws JCoException {
      Properties pp = getJcoProperties();
      PropertiesDestinationDataProvider pddp = new PropertiesDestinationDataProvider(pp);
      Environment.registerDestinationDataProvider(pddp);
		
      JCoDestination dest = getDestination();
		
      try {
          JCoContext.begin(dest);       
          JCoRepository sapRepository = dest.getRepository();
          System.out.println(sapRepository.getMonitor().getLastAccessTimestamp());
       } finally {
         JCoContext.end(dest);
       }
   }
}  

You should see the date when you access the system last time:

Tue Mar 07 18:14:25 CET 2017

In the next post, we will see how to call SAP BAPI to create, delete, update SAP users.

ps. To simplify working with code, I have also created a gradle script:

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'
apply plugin: 'pmd'
apply plugin: 'checkstyle'

sourceSets {
  main {
    java {
      srcDirs  = ['src']
    }
    resources {
      srcDirs = ['src']
    }
  }
  
  test {
    java {
      srcDirs = ['test']
    }
    
    resources {
      srcDirs = ['test']
    }
  }
  
}

checkstyle {
  toolVersion = '7.6'
}

mainClassName = "pl.wbarczynski.sap.cli.CreateLogonUsers"

dependencies {

  // this goodie, you need to grab from SAP marketplace

  compile files('lib/sapjco3.jar')
  testCompile group: 'junit', name:'junit', version: '4.10'
}

repositories {
  mavenCentral()
}

We will use it to run our CLI in few posts from now.

 

wb