GlassFish和SAP JCo连接器(sapjco3.jar
)有问题。
我在启动J2EE应用程序(jwm.ear
)时加载它,并在第一次需要连接到SAP时将其初始化为一个单例。
问题是这个jar总是在内存中保持初始化,如果我需要更改一个参数,我需要重新启动glassfish来卸载初始化的连接。停止或取消部署应用程序不会卸载sapjco.jar,并且应用程序的进一步重新部署永远不会获得新的连接参数,第一次初始化将保留到GlassFish重新启动。
有人知道如何卸载或重新初始化这个库吗?优选地,即使不重新部署应用程序,应用程序第一次被激活时,I具有对jcoProvider的引用,下一次激活获得对jcoProvider的空引用,但是jcoProvider继续在存储器中以初始值示例化。
问候!Notes: GlassFish is version 2.1 in Windows 2008 server, jdk is 1.6.0.14 sapjco3.jar and sapjco3.dll are copied to \domains\domain1\lib\ext and are version 3 of SAP java connector.
Singleton用于获取SAP连接:
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提供程序实现:
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());
}
}
}
2条答案
按热度按时间kpbwa7wx1#
您的问题可能与这里涉及一些本机代码的事实有关。对于JCo 3来说也是如此。尽管JCo3不再使用本机RFC库,但它仍然需要JNI来与CPIC层通信。
让JVM卸载本机库是一项极其令人沮丧的工作。JNI规范指出,当与它提供实现的类相关联的ClassLoader被卸载时,本机库将被卸载,但试图强制ClassLoader卸载在JVM中几乎是不可能的。
如果您的EAR文件包含sapjco3.jar,则每次重新加载代码时都会重新加载它。这很可能会导致异常,因为本机库不能加载一次以上,并且实际上没有办法卸载本机代码。因此,您可以考虑将sapjco3.jar放在J2EE容器之外,让J2EE引擎在启动时加载该库一次,而不是将其放入EAR中,然后反复重新加载。
nmpmafwu2#
您打算连接到哪个版本的SAP?Java连接器有几个问题,它不是真正的线程安全的,不能正确地嵌入到EJB应用程序中。同样的问题也出现在SAP的seculib单点登录上。要么就是不管用。唯一的解决方案是在J2EE引擎之外加载它。
你有没有想过用Web服务取代JCO?当然,由于数据必须经过ICF,因此它稍微慢一些,但它更强大。我们将所有的集成都切换到了这个解决方案。