加载本机库时,OSGI框架会挂起

时间:2012-03-02 12:50:25

标签: java windows dll service osgi

情况:开源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;

}

1 个答案:

答案 0 :(得分:0)

您描述的情况有两个可能的问题;我不确切知道Equinox如何处理本机代码,所以我只是将它们呈现给你们。

Bundle-NativeCode至少需要一个参数

您使用仅定义库的Bundle-NativeCode标头,并且您似乎使用Eclipse-PlatformFilter来指定该库的用途。 spec的第3.10节显示您需要至少一个参数来选择库。

您可以将Bundle-NativeCode标题更改为

Bundle-NativeCode: ntfsacl/Release/NtfsAcl.dll;osname=win32

您的捆绑包将能够找到合适的库。

仅从您自己的捆绑中加载

从您的代码判断,您可以在一个包中定义库,并尝试将其加载到另一个包中;如果不起作用,bundle只能加载它自己包含的库。