java - 加载 native 库时 OSGI 框架挂起

标签 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 的 list :

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+

包含代码的 list :

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;

}

最佳答案

您所描述的情况可能有两个问题;我不太清楚 Equinox 是如何处理 native 代码的,所以我只是将它们介绍给你们俩。

Bundle-NativeCode 需要至少一个参数

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

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

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

并且您的包将能够找到正确的库。

仅从您自己的包加载

从您的代码来看,您可能在一个包中定义了该库,并尝试将其加载到另一个包中;这是行不通的,包只能加载它本身包含的库。

关于java - 加载 native 库时 OSGI 框架挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9533595/

相关文章:

c++ - 如何在 VC++ 中更改 __stdcall 的导出名称修饰?

c# - Visual C# 找不到我的 Ionic Zip .dll 文件

java - 操作系统如何决定如何运行 .exe

java - Android中执行后台定时重复任务,以及IntentService和Runnable的区别

javascript - 从 NodeJS 调用 PowerShell

c# - 在 C# 中将字符串作为批处理文件运行

windows - Delphi 中按钮的自定义窗口提示

java - 以我不需要安装的方式嵌入Java3D是不可能的吗?

java - Spring过滤器抛出自定义异常

java - 保存 WebView 的状态并重新加载位置