GlassFish と SAP JCo コネクタ (sapjco3.jar) に問題があります。
J2EE アプリケーション (jwm.ear) の起動時にロードし、SAP への接続が初めて必要になったときにシングルトンにラップして初期化します。
問題は、この jar がメモリ内で常に初期化されたままになることです。単一のパラメーターを変更する必要がある場合は、初期化された接続をアンロードするために Glassfish を再起動する必要があります。アプリを停止またはアンデプロイしても sapjco.jar がアンロードされず、アプリをさらに再デプロイしても新しい接続パラメーターが取得されず、GlassFish が再起動するまで最初の初期化が残ります。
このライブラリをアンロードまたは再初期化する方法を知っている人はいますか? できればアプリを再デプロイしなくても、最初にアプリがアクティブ化されたときに jcoProvider への参照があり、次のアクティブ化では jcoProvider への null 参照が取得されますが、jcoProvider は初期値でメモリ内でインスタンス化され続けます。
よろしく!
注: GlassFish は Windows 2008 サーバーのバージョン 2.1、jdk は 1.6.0.14 です。
SAP 接続を取得するためのシングルトン:
パッケージ es.grupotec.ejb.SAP; com.sap.conn.jco.JCoDestination をインポートします。 com.sap.conn.jco.JCoDestinationManager をインポートします。 インポート com.sap.conn.jco.JCoException; com.sap.conn.jco.ext.DestinationDataProvider をインポートします。 com.sap.conn.jco.ext.Environment をインポートします。 es.grupotec.ejb.util.ConexionSAPException をインポートします。 java.util.Properties をインポートします。 公開最終クラス SAP { private static String SAP_SERVER = "JWM"; プライベート静的 SAP インスタンス = null; プライベート静的 JCOProvider jcoProvider = null; プライベート SAP() { // インスタンス化を無効にするためだけに存在します。 } // SAP 接続を取得 public static synchronized JCoDestination getDestination() は ConexionSAPException をスローします { JCoDestination jcoDestination = null; if (Environment.isDestinationDataProviderRegistered()) { 試す { jcoDestination = JCoDestinationManager.getDestination(SAP_SERVER); jcoDestination を返します。 } catch (JCoException ex) { 新しい ConexionSAPException(ex.getMessage()) をスローします。 } } // 新しい接続を作成します if(jcoProvider == null) init(); // 接続を取得 試す { jcoDestination = JCoDestinationManager.getDestination(SAP_SERVER); jcoDestination を返します。 } catch (JCoException ex) { 新しい ConexionSAPException(ex.getMessage()) をスローします。 } } // SAP への接続を初期化します public static synchronized void init() throws ConexionSAPException { SAPVO sap = 新しい SAPVO(); プロパティ プロパティ = 新しいプロパティ(); if(jcoProvider == null) { // データベースから SAP 構成を取得します 試す { 樹液 = SAPDAO.getSAPConfig(); } catch (例外例) { 新しい ConexionSAPException(ex.getMessage()) をスローします。 } // 接続オブジェクトを作成 jcoProvider = 新しい 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()); 試す { jcoProvider.changePropertiesForABAP_AS(プロパティ); キャッチ(例外e){ 新しい ConexionSAPException(e.getMessage()) をスローします。 } } public static synchronized void change(SAPVO sap) throws ConexionSAPException { プロパティ プロパティ = 新しいプロパティ(); // 接続が null の場合、新しい接続を作成します 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()); 試す { jcoProvider.changePropertiesForABAP_AS(プロパティ); キャッチ(例外e){ 新しい ConexionSAPException(e.getMessage()) をスローします。 } } // クローンによるインスタンス化を防ぐ @オーバーライド public Object clone() は CloneNotSupportedException をスローします { 新しい CloneNotSupportedException() をスローします。 } }
JCo プロバイダーの実装:
パッケージ es.grupotec.ejb.SAP; import com.sap.conn.jco.ext.DestinationDataEventListener; com.sap.conn.jco.ext.DestinationDataProvider をインポートします。 com.sap.conn.jco.ext.Environment をインポートします。 es.grupotec.ejb.util.ConexionSAPException をインポートします。 java.util.Properties をインポートします。 public class JCOProvider は DestinationDataProvider を実装します { private String SAP_SERVER = "JWM"; プライベート DestinationDataEventListener eventListener; プライベート プロパティ ABAP_AS_properties; public JCOProvider(){ } public JCOProvider(SAPVO sap){ ABAP_AS_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()); 試す { if (!Environment.isDestinationDataProviderRegistered()) Environment.registerDestinationDataProvider(これ); そうでなければchangePropertiesForABAP_AS(ABAP_AS_properties); } catch (例外例) { 文字列 msg = ex.getMessage(); } } @オーバーライド パブリック プロパティ getDestinationProperties(文字列名) { if (name.equals(SAP_SERVER) && ABAP_AS_properties!=null) return ABAP_AS_properties; それ以外の場合は null を返します。 } @オーバーライド public boolean supportsEvents() { true を返します。 } @オーバーライド public void setDestinationDataEventListener(DestinationDataEventListener eventListener) { this.eventListener = eventListener; } public void changePropertiesForABAP_AS(プロパティ プロパティ) は ConexionSAPException をスローします { 試す { if (!Environment.isDestinationDataProviderRegistered()) { if (ABAP_AS_properties == null) ABAP_AS_properties = プロパティ; Environment.registerDestinationDataProvider(これ); } if (プロパティ == null) { if (eventListener != null) eventListener.deleted(SAP_SERVER); ABAP_AS_properties = null; } そうしないと { ABAP_AS_properties = プロパティ; if (eventListener != null) eventListener.updated(SAP_SERVER); } } catch (例外例) { 新しい ConexionSAPException(ex.getMessage()) をスローします。 } } }