cancel
Showing results for 
Search instead for 
Did you mean: 

SAP JCo: How to handle an Exception thrown by JCoContext.end()

Former Member
0 Kudos

All,

We have currently developed a Java client application that communicates with SAP via the JCO v3.0 API. During a stateful call, where multiple BAPI functions are invoked, we use the JCoContext class to establish a stateful session. We call JCoContext.begin() before the JCoFunctions are executed and JCoContext.end() in a finally block after all functions are complete.

The problem arises on JCoContext.end(). It could potentially raise a JCoException. The document is not very clear on why an Exception may occur or how to handle it. In testing, I have been able to observe an exception when a NULL destination is passed to the JCoContext.end() method. While this can occur, it most definitely will not occur in our production code. So the question remains, are there any other reasons why and exception would be raised?

Also, I have observed strange behavior if the JCoContext.end() method is not invoked. It those cases, I have seen subsequent BAPI calls not complete successfully. This indicates to me that if the end() method does not complete successfully, it could leave the JCo in a bad state. So, how should we handle an exception that occurs here. What recourse do I have as a developer?

Thanks,

Paul Manning

Accepted Solutions (1)

Accepted Solutions (1)

HAL9000
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Paul,

that's a good question!

If your workflow within the try-finally-block would allow that the destination object might not have been initialized and used yet and therefore it is still null, then I would simply call the JCoContext.end(destination) only if the destination is not null:

finally

{

    if (destination!=null)

        JCoContext.end(destination);

}

There should not be any other exception here, and if so nevertheless, I don't think that one could recover from it programmatically. Then there's most likely some severe bug in the coding: either in JCo itself or the registered SessionReferenceProvider. I suggest to open a SAP support ticket in such cases.

And to your other question:

If JCoContext.end(destination) is not invoked for your destination object, it will remain in stateful mode for your current session with all the desired consequences like uncommited LUWs and attached RFC contexts at ABAP back-end side which are then still being bound to it. The next time you will do a call to this destination in the same session, you might get other results than expected in contrast to a fresh and clean connection.

Also, if you don't call JCoContext.end(destination) in your session you have produced a connection leak where the appropriate stateful RFC connection will remain reserved and open forever.

Best regards,

Stefan

Former Member
0 Kudos

Thank you Stefan. Your explanation matches our current assumptions.

We have never actually witnessed an exception being thrown here. However, the Javadoc is very vague. The documentation on the JCoContext.end() method states:

   throws JCoException - in case releasing/closing the connection runs into an issue

So, while your explanation makes sense, I am still paranoid of a production issue here in this code .

It is also worth noting that our code currently ensures that the "destination" parameter passed into the JCoContext.end() method is never NULL. That is the only case where we have observed an exception and it was a purposely contrived case at that.


My main concern was the lack of documentation on this. Also, I could not find any public APIs to recover the JCoContext in the event of an exception. During some testing where we purposely excluded the end() method call, we observed the behavior that you have described, ie. corrupt LUWs/Contexts.


More details from others are appreciated.


Thanks,


Paul

Answers (1)

Answers (1)

vijay_kumar49
Active Contributor
0 Kudos

Try this syntax. it should be useful. check this example code Example-1 and Example-2

JCoDestination destination = JCoDestinationManager.getDestination("<destination>");

  try

  {

  JCoContext.begin(destination);

  function1.execute(destination);

  function2.execute(destination);

  functionBapiTransactionCommit.execute(destination);

  }

  catch (AbapException ex)

  {

  ...

  }

  catch (JCoException ex)

  {

  ...

  }

  catch (Exception ex)

  {

  ...

  }

  finally

  {

  JCoContext.end(destination);

  }

Kindly let me know if you need any more information

Former Member
0 Kudos

Unfortunately, this answer is not helpful. You posted the example code which is publicly available in the SAP JCo Help documentation. This code exhibits the problem that I described in my original post. The question remains, what do you do in the "finally" block if the JCoContext.end() method throws an exception. Under what conditions does this method throw an exception? If the JCoContext is corrupt at that point, what recourse do you have? Can you safely call JCoContext.begin() again for subsequent BAPI calls? Since the JCoContext methods are static, I cannot create a new clean one. Subsequent calls to JCoContext.begin() without a proper end() method might assume a nested context.

Right now, my code effectively looks something like this...

try

{

  JCoContext.begin(destination);

  function1.execute(destination);

  ...

}

finally

{

  try

  {

    JCoContext.end(destination);

  }

  catch(Exception ex)

  {

    LOG.error("Error occured while trying to close the JCoContext");

  }

}

So, in the code above, we are just logging that the exception occurred and moving on. However, without fully understanding what JCoContext.end() is doing, I am not confident in this approach.

-Paul