情况:开源OSGI框架SMILA(http://www.eclipse.org/smila/)在Apache commons-daemon(http://commons.apache.org/daemon/)的帮助下作为Windows服务启动。尝试通过System.loadLibrary()
从OSGI包加载DLL,Manifest.mf
包括Bundle-NativeCode: path/to/dll
。
环境:Windows Server 2003,Java 1.6
错误:在调用System.loadLibrary()
期间,完整的Java进程挂起。当服务停止时System.loadLibrary()
完成并且代码执行继续,直到OSGI框架关闭。
Windows Server 2008上未出现错误,或者OSGI框架未作为服务启动。
DLL本身被剥离为没有用于测试的功能。所有导入都是静态的,唯一依赖的库是kernel32.ddl
。
有谁能想象为什么会发生这种情况以及如何解决这个问题?
包含DLL的清单:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NTFS Utils Acl Win32 Library
Bundle-SymbolicName: com.eccenca.utils.ntfs.acl.win32
Bundle-Version: 2.2.0
Bundle-Vendor: brox IT-Solutions GmbH
Fragment-Host: com.eccenca.utils.ntfs
Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86))
Bundle-NativeCode: ntfsacl/Release/NtfsAcl.dll
Bundle-RequiredExecutionEnvironment: JavaSE-1.6+
包含代码的清单:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NTFS Utils Acl
Bundle-SymbolicName: com.eccenca.utils.ntfs
Bundle-Version: 2.2.0
Bundle-Vendor: brox IT-Solutions GmbH
Export-Package: com.eccenca.processing.acl,
com.eccenca.utils.ntfs
Import-Package: org.apache.commons.io;version="1.4.0",
org.apache.commons.lang,
org.apache.commons.logging;version="1.1.1",
org.eclipse.smila.blackboard;version="0.8.0",
org.eclipse.smila.datamodel,
org.eclipse.smila.processing;version="0.8.0",
org.eclipse.smila.processing.pipelets;version="0.8.0",
org.eclipse.smila.utils.config;version="0.8.0",
org.eclipse.smila.utils.service;version="0.8.0",
org.osgi.framework;version="1.4.0"
SMILA-Pipelets: com.eccenca.processing.acl.AccessListConverterPipelet
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
使用System.loadLibrary()
调用截断的代码:
public class ACLList {
private static final org.apache.commons.logging.Log LOG =
org.apache.commons.logging.LogFactory.getLog(ACLList.class);
static {
try {
LOG.debug("Start loading library");
System.loadLibrary("NtfsAcl");
if (LOG.isInfoEnabled()) {
LOG.info("NTFS ACL library was succesfully loaded");
}
} catch (Throwable e) {
LOG.error(e);
}
}
private ACLList() {
}
public static native ArrayList<ACLEntry> getAccessFor(String path,
String serverName) throws IOException;
}
答案 0 :(得分:0)
您描述的情况有两个可能的问题;我不确切知道Equinox如何处理本机代码,所以我只是将它们呈现给你们。
您使用仅定义库的Bundle-NativeCode
标头,并且您似乎使用Eclipse-PlatformFilter
来指定该库的用途。 spec的第3.10节显示您需要至少一个参数来选择库。
您可以将Bundle-NativeCode
标题更改为
Bundle-NativeCode: ntfsacl/Release/NtfsAcl.dll;osname=win32
您的捆绑包将能够找到合适的库。
从您的代码判断,您可以在一个包中定义库,并尝试将其加载到另一个包中;如果不起作用,bundle只能加载它自己包含的库。