SAP JCo Connector permanently loaded into GlassFish v2.1 (cannot be unloaded)

I have a problem with GlassFish and SAP JCo Connector (sapjco3.jar)

I download it when I launch the J2EE application (jwm.ear) and initializes it, wrapped in a singleton, the first time I connect to SAP.

The problem is that this jar is always initialized in memory, I need to restart the old chip in order to unload the initialized connections if I need to change one parameter. Stopping or disabling the application does not unload sapjco.jar, and redeploying the application never gets new connection parameters, the first initialization remains until the GlassFish restarts.

Does anyone know how to unload or reinitialize this library? preferably even without redeploying the application, the first time I launch the application, I have a link to jcoProvider, the following activations get a null reference to jcoProvider, but jcoProvider continues to create instances in memory with initial values.

Hello!

Notes: GlassFish - version 2.1 on the Windows 2008 server, jdk - 1.6.0.14 sapjco3.jar and sapjco3.dll are copied to \ domains \ domain1 \ lib \ ext and are version 3 of the Java java connector.

Singleton for getting SAP connections:

  package es.grupotec.ejb.SAP;

 import com.sap.conn.jco.JCoDestination;
 import com.sap.conn.jco.JCoDestinationManager;
 import com.sap.conn.jco.JCoException;
 import com.sap.conn.jco.ext.DestinationDataProvider;
 import com.sap.conn.jco.ext.Environment;
 import es.grupotec.ejb.util.ConexionSAPException;
 import java.util.Properties;

 public final class SAP {

     private static String SAP_SERVER = "JWM";
     private static SAP instance = null;
     private static JCOProvider jcoProvider = null;

     private SAP () {
       // Exists only to defeat instantiation.
     }

     // Get SAP connection
     public static synchronized JCoDestination getDestination () throws ConexionSAPException {

         JCoDestination jcoDestination = null;

             if (Environment.isDestinationDataProviderRegistered ()) {
                 try {

                     jcoDestination = JCoDestinationManager.getDestination (SAP_SERVER);
                     return jcoDestination;

                 } catch (JCoException ex) {

                     throw new ConexionSAPException (ex.getMessage ());

                 }
             }

         // Create new connection
         if (jcoProvider == null) init ();

         // Get connection
         try {

             jcoDestination = JCoDestinationManager.getDestination (SAP_SERVER);
             return jcoDestination;

         } catch (JCoException ex) {

             throw new ConexionSAPException (ex.getMessage ());

         }

     }

     // Initialize connection to SAP
     public static synchronized void init () throws ConexionSAPException {

         SAPVO sap = new SAPVO ();
         Properties properties = new Properties ();

         if (jcoProvider == null) {


             // Get SAP config from database
             try {
                 sap = SAPDAO.getSAPConfig ();
             } catch (Exception ex) {
                 throw new ConexionSAPException (ex.getMessage ());
             }

              // Create connection object
             jcoProvider = new JCOProvider ();

         }

         properties.setProperty (DestinationDataProvider.JCO_ASHOST, sap.getJCO_ASHOST ());
         properties.setProperty (DestinationDataProvider.JCO_SYSNR, sap.getJCO_SYSNR ());
         properties.setProperty (DestinationDataProvider.JCO_CLIENT, sap.getJCO_CLIENT ());
         properties.setProperty (DestinationDataProvider.JCO_USER, sap.getJCO_USER ());
         properties.setProperty (DestinationDataProvider.JCO_PASSWD, sap.getJCO_PASSWD ());
         properties.setProperty (DestinationDataProvider.JCO_LANG, sap.getJCO_LANG ());

         try {

             jcoProvider.changePropertiesForABAP_AS (properties);

         } catch (Exception e) {

             throw new ConexionSAPException (e.getMessage ());

         }

     }

     public static synchronized void change (SAPVO sap) throws ConexionSAPException {

         Properties properties = new Properties ();

         // If connection is null create a new one
         if (jcoProvider == null) jcoProvider = new JCOProvider ();

         properties.setProperty (DestinationDataProvider.JCO_ASHOST, sap.getJCO_ASHOST ());
         properties.setProperty (DestinationDataProvider.JCO_SYSNR, sap.getJCO_SYSNR ());
         properties.setProperty (DestinationDataProvider.JCO_CLIENT, sap.getJCO_CLIENT ());
         properties.setProperty (DestinationDataProvider.JCO_USER, sap.getJCO_USER ());
         properties.setProperty (DestinationDataProvider.JCO_PASSWD, sap.getJCO_PASSWD ());
         properties.setProperty (DestinationDataProvider.JCO_LANG, sap.getJCO_LANG ());

         try {

             jcoProvider.changePropertiesForABAP_AS (properties);

         } catch (Exception e) {

             throw new ConexionSAPException (e.getMessage ());

         }


     }

     // Prevent instantiation by clone
     @Override
     public Object clone () throws CloneNotSupportedException {

         throw new CloneNotSupportedException ();

     }

 }

JCo Provider Implementation:

  package es.grupotec.ejb.SAP;

 import com.sap.conn.jco.ext.DestinationDataEventListener;
 import com.sap.conn.jco.ext.DestinationDataProvider;
 import com.sap.conn.jco.ext.Environment;
 import es.grupotec.ejb.util.ConexionSAPException;
 import java.util.Properties;

 public class JCOProvider implements DestinationDataProvider {

     private String SAP_SERVER = "JWM";
     private DestinationDataEventListener eventListener;
     private Properties ABAP_AS_properties;

     public JCOProvider () {

     }

     public JCOProvider (SAPVO sap) {

         ABAP_AS_properties = new Properties ();
         ABAP_AS_properties.setProperty (DestinationDataProvider.JCO_ASHOST, sap.getJCO_ASHOST ());
         ABAP_AS_properties.setProperty (DestinationDataProvider.JCO_SYSNR, sap.getJCO_SYSNR ());
         ABAP_AS_properties.setProperty (DestinationDataProvider.JCO_CLIENT, sap.getJCO_CLIENT ());
         ABAP_AS_properties.setProperty (DestinationDataProvider.JCO_USER, sap.getJCO_USER ());
         ABAP_AS_properties.setProperty (DestinationDataProvider.JCO_PASSWD, sap.getJCO_PASSWD ());
         ABAP_AS_properties.setProperty (DestinationDataProvider.JCO_LANG, sap.getJCO_LANG ());
         ABAP_AS_properties.setProperty (DestinationDataProvider.JCO_POOL_CAPACITY, sap.getJCO_POOL_CAPACITY ());
         ABAP_AS_properties.setProperty (DestinationDataProvider.JCO_PEAK_LIMIT, sap.getJCO_PEAK_LIMIT ());

         try {
             if (! Environment.isDestinationDataProviderRegistered ())
                 Environment.registerDestinationDataProvider (this);
             else changePropertiesForABAP_AS (ABAP_AS_properties);
         } catch (Exception ex) {
             String msg = ex.getMessage ();
         }

     }

     @Override
     public Properties getDestinationProperties (String name) {

         if (name.equals (SAP_SERVER) && ABAP_AS_properties! = null) return ABAP_AS_properties;
         else return null;

     }

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

     @Override
     public void setDestinationDataEventListener (DestinationDataEventListener eventListener) {
         this.eventListener = eventListener;
     }

  public void changePropertiesForABAP_AS (Properties properties) throws ConexionSAPException {

         try {

             if (! Environment.isDestinationDataProviderRegistered ()) {

                 if (ABAP_AS_properties == null) ABAP_AS_properties = properties;
                 Environment.registerDestinationDataProvider (this);

             }

             if (properties == null) {

                 if (eventListener! = null) eventListener.deleted (SAP_SERVER);
                 ABAP_AS_properties = null;

             } else {

                 ABAP_AS_properties = properties;
                 if (eventListener! = null) eventListener.updated (SAP_SERVER);

             }

         } catch (Exception ex) {

             throw new ConexionSAPException (ex.getMessage ());

         }

  }

 }

+4
source share
2 answers

Your problem is probably due to the fact that some kind of native code is present here. This is true for JCo 3. While JCo 3 no longer uses the national RFC library, it still needs JNI to bind to the CPIC layer.

Getting the JVM to unload the native library is an exercise with maximum frustration. The JNI specification indicates that the native library will be unloaded when the ClassLoader associated with the class that it provides for implementation is unloaded, but trying to force ClassLoader to unload in the JVM is almost impossible.

If your EAR file contains the sapjco3.jar file, it will be reloaded every time your code is reloaded. This will most likely lead to exceptions, since the native library cannot be loaded more than once, and it is almost impossible to unload your own code. Thus, you can consider placing sapjco3.jar outside the J2EE container and let your J2EE engine load this library once at startup, rather than putting it in an EAR that reloads again and again.

+3
source

What version of SAP are you planning to connect to? We had several problems with the Java Connector, it was not really thread-safe and could not be correctly implemented in the EJB application. The same issues arose with SAP seculib for single sign-on. It either didn't work. The only solution was to load it outside the J2EE mechanism.

Have you ever thought about replacing JCO with web services? Of course, this is a bit slower as the data must pass through the ICF, but it is more reliable. We have included all our integration in this solution.

0
source

All Articles