cancel
Showing results for 
Search instead for 
Did you mean: 

Number of execute Threads

Former Member
0 Kudos

Hi JCO experts,

I need some help, We are using JCO for our backend rfc calls.

I noticed that our application ran out of number of connections configured to SAP and it started throwing exceptions during a certain time frame. That's all fine. However, currently, the stats are looking like this:

Number of connection currently used 0

Thread waiting for connections 807

Current connections alive (Used + unused) 4

In other words,

pool.getNumUsed() = 0

pool.getNumWaitingThreads() = 807

pool.getCurrentPoolSize() = 4

I don't understand why number of Thread waiting is so high when connections are available in the pool.

Am I missing something here.. Are these stuck threads? If that's the case, my application should at one time choke but it's running fine..

If you have run into something like this, please help.

Env Solaris

Jco Version: latest

thanks

Accepted Solutions (0)

Answers (1)

Answers (1)

Former Member
0 Kudos

Try showing some code. Are you closing the connections in a finally clause. This will release the connection back into the pool for further use. Try this.

Connection Conn = null;

try{

}catch (Exception ex){

}finally{

try{conn.close();}catch(Exception ez){}

}

Former Member
0 Kudos

Thanks for looking at it, here is the method call..


protected void execute(JCO.Function function)
        throws SapConnectionException{

        JCO.Client client = null;
        long duration=System.currentTimeMillis();

        try{
            client = SapConnectionFactory.getInstance().getConnection();
            client.execute(function);
            duration=System.currentTimeMillis()-duration;
            this.logStatistics(duration);
        }
        catch(JCO.Exception e){
            error("JCO Exception :"+ e.getMessage());
            new SapConnectionException(e);
        }
        catch(Exception e){
            error(e);
            new SapConnectionException(e);
        }
        finally{
            if (client != null){
                JCO.releaseClient(client);
            }
        }
    }

Former Member
0 Kudos

Is this the code within your Bean? Maybe it would be better to supply the code of your Pool Connection class. SAPConnectionFactory?

I'm not sure why you pass in a JCO.Function into the execute method. To get a function you need a repository and to get a repository you need a JCO.Client. So if you are keeping the functions and repositories held up, then the connection would not be set free.

Can't tell either way with the code you supplied.

Former Member
0 Kudos

Adding the code for SapConnectionFactory



import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Properties;

import com.sap.mw.jco.JCO;
import com.sap.mw.jco.IFunctionTemplate;

public final class SapConnectionFactory {

    private static Log gLog = LogFactory.getLog(SapConnectionFactory.class);
    private static SapConnectionFactory mFactory = null;
    protected static String mPoolName = "SDD_SAP_POOL";
    private static SapRepository mRepository = null;


    protected static SapConnectionFactory getInstance(){
	if (mFactory == null){
	    mFactory = new SapConnectionFactory(mPoolName);
	}

	assert(mFactory != null);
    	return mFactory;
    }


    private SapConnectionFactory(String poolName) {
    	// not meant to be instantiated
	createPool(poolName);
    }


    private synchronized void createPool(String poolName){

	gLog.info("Creating sap pool with pool name:" + poolName);
    	JCO.PoolManager pm = JCO.getClientPoolManager().singleton();

	try{
		/* Repository instance is created which is just our 
		 * class extending from JCO.Repository. 
		 * We are giving it a pool name so repository can 
		 * get us function template if one does not exist in cache
		 */	

		repository = SapRepository.getInstance(poolName);
		// Read properties here	
		JCO.addClientPool(poolName, 20, properties);
	    }
	}
	catch(JCO.Exception e){
	    fatal(e);
	}


    }


    public JCO.Client getConnection() 
		throws SapConnectionException {

	JCO.Client client = null;

	try {
	    client = JCO.getClient(poolName);
	    
	    JCO.PoolManager pm = JCO.getClientPoolManager().singleton();
	    JCO.Pool pool = pm.getPool(poolName);
	   
	}catch(JCO.Exception e){
	    if (e.JCO_ERROR_RESOURCE == e.getGroup()){
		gLog.fatal(
		    "*** NO more SAP connections available from pool: ***");
	    }
	    else{
	        gLog.fatal("SAP connection error!!!!!!"+ e.getMessage() 
		    + "Stack trace followed");
		e.printStackTrace();
	    }	
	    throw new SapConnectionException(e);
	}

	assert(client != null);
	return(client);
    }
    
    protected JCO.Function getFunction(String rfcName) 
	throws SapConnectionException{

	JCO.Function function = null;	
	if (isDebugEnabled()){
	    debug("Getting Function template for "+ rfcName);
	}
	try{
	    IFunctionTemplate ft = mRepository.getFunctionTemplate(rfcName);
	    if (ft == null){
		debug("Function template is null for"+ rfcName);
	    }
	    if (ft != null){
		function = ft.getFunction();
	    }
	}
	catch(JCO.Exception e){
	    error("Unable to get Function template from SAP"+ e.getMessage());
	    throw new SapConnectionException(e);
	}
	catch(Exception e){
	    error("Fatal error , unable to get Function template from SAP "+ 
		e.getMessage());
	    throw new SapConnectionException(e);
	}
	return function;
    }
}


Former Member
0 Kudos

what is the assert method?

It seems that you are doing this on the tomcat app server?

Former Member
0 Kudos

Correct, but this is a generic code and I believe it can run on any app server.

Assert is simply a Java assertion (JDK, 1.4.2_05), but that again is not an issue here.