加载本地库时,OSGI框架挂起 [英] OSGI framework hangs when loading native library

查看:109
本文介绍了加载本地库时,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版本:2.2.0
捆绑供应商: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-版本:2.2.0
捆绑供应商:brox IT-Solutions GmbH
出口 - 软件包:com.eccenca.processing.acl,
com.eccenca.utils.ntfs
导入包: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(开始加载库);
System.loadLibrary(NtfsAcl);
if(LOG.isInfoEnabled()){
LOG.info(NTFS ACL库已成功加载);
}
} catch(Throwable e){
LOG.error(e);
}
}

private ACLList(){
}

public static native ArrayList< ACLEntry> getAccessFor(String path,
String serverName)throws IOException;

}


解决方案

与你描述的情况有两个可能的问题;我不知道Equinox如何处理本地代码,所以我只是向他们介绍两者。



Bundle-NativeCode至少需要一个参数



您使用一个 Bundle-NativeCode 头,只需定义一个库,似乎您使用 Eclipse- PlatformFilter 来指定该库的目的。 规格的第3.10节显示,您需要至少一个参数来选择库。 / p>

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

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

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



仅从您自己的包中加载



从您的代码中可以看出,您可以将库定义在一个包中,并尝试将其加载到另一个包中。这不起作用,捆绑包只能加载其自身包含的库。


Situation: Open source OSGI framework SMILA (http://www.eclipse.org/smila/) started as Windows Service with the aid of Apache commons-daemon (http://commons.apache.org/daemon/). Trying to load a DLL via System.loadLibrary() from OSGI bundle while Manifest.mf includes Bundle-NativeCode: path/to/dll.

Environment: Windows Server 2003, Java 1.6

Error: During the invocation of System.loadLibrary() the complete Java process hangs. When the service is stopped System.loadLibrary() finish and code execution goes on until the OSGI framework shut down.

The error doesn’t occur on Windows Server 2008 or if the OSGI framework isn’t started as service.

The DLL itself is stripped down to no functionality for testing. All imports are static and the only depended library is kernel32.ddl.

Could anyone imagine why this is happening and how to fix it?


Manifest containing 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 containing code:

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

Code snipped with System.loadLibrary() invocation:

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;

}

解决方案

There are two possible issues with the situation you described; I don't know exactly how Equinox handles native code, so I'll just present them to you both.

Bundle-NativeCode requires at least one parameter

You use a Bundle-NativeCode header that just defines a library, and it seems you use Eclipse-PlatformFilter to specify what that library is intended for. Section 3.10 of the spec shows that you need at least one parameter for the library to be selected.

You can change your Bundle-NativeCode header to read

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

and your bundle will be able to find the right library.

Load only from your own bundle

Judging from your code, it could be possible that you define the library in one bundle, and try to load it in another; that doesn't work, a bundle can only load a library that it contains itself.

这篇关于加载本地库时,OSGI框架挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆