【问题标题】:OSGI framework hangs when loading native library加载本机库时 OSGI 框架挂起
【发布时间】:2012-03-02 12:50:24
【问题描述】:

情况:开源 OSGI 框架 SMILA (http://www.eclipse.org/smila/) 在 Apache commons-daemon (http://commons.apache.org/daemon/) 的帮助下作为 Windows 服务启动.尝试从 OSGI 包中通过 System.loadLibrary() 加载 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;

}

【问题讨论】:

  • 能否包含一些代码,以及更完整的捆绑清单?
  • 当然。我只是编辑我的问题。谢谢。
  • 也许jstack 可以展示一些有用的东西。

标签: java windows dll service osgi


【解决方案1】:

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

Bundle-NativeCode 至少需要一个参数

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

您可以将Bundle-NativeCode 标头更改为读取

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

您的捆绑包将能够找到正确的库。

仅从您自己的包中加载

从您的代码来看,您可以在一个包中定义库,然后尝试在另一个包中加载它;这不起作用,一个包只能加载它包含自己的库。

【讨论】:

  • 感谢您的提示。我按照建议将参数“osname”添加到我的清单中。不幸的是,什么都没有改变。此外,我将库与代码一起移动到一个包中。也没有生效。由于包含 DLL 的包是包含代码的包的片段,因此无论如何它应该可以工作。
  • 在启动时设置 java 参数 java.library.path=folder/包含/dll(在包之外)之前,我也尝试过没有任何 OSGI 和本机代码特定的东西。调用 System.loadLibrary() 时,框架总是挂起。该问题与找不到DLL无关;框架只是在加载时挂起。直到关闭 OSGI 框架的代码执行才继续。
  • 奇怪的是,当库不由 OSGi 管理时它也会挂起。如果我是你,我会在 Equinox 邮件列表上问这个问题,看看这是否是你使用的确切操作系统上的已知问题。
猜你喜欢
  • 1970-01-01
  • 2015-11-22
  • 2015-10-15
  • 2012-07-07
  • 2015-08-17
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 2012-03-10
相关资源
最近更新 更多