不满意的链接错误:库加载但我仍然收到链接错误 [英] UnsatisfiedLinkError: The library loads but I still get a link error

查看:302
本文介绍了不满意的链接错误:库加载但我仍然收到链接错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个Eclipse插件:




  • plugin-1:在.jar中为其他插件提供了一个包。 (C ++库的Java Wrapper)此插件是通过从现有JAR存档中单击File-> New-> Other-> Plug-in创建的。


  • plugin-2:具有插件1( Bundle-NativeCode 指令在MANIFEST.MF中)的本地库.so,并从plugin-1实例化一个类




(我实际上尝试将.so放在plugin-1中,但我似乎无法加载库,即使是Bundle- NativeCode指令在插件1 MANIFEST.MF中,在包含.so的插件项目之外,所以我想我必须将.so与使用plugin-1的任何插件捆绑。)



我正在从plugin-2运行一个JUnit测试,它从plugin-2中实例化 MyClass ,然后实例化 MyLibraryClass from plugin-1。 MyClass 成功加载本地库并实例化 MyLibraryClass 而不使用 UnsatisfiedLinkError 或从加载本机库或从实例化的 MyLibraryClass 抛出的其他异常。在这种情况下,我没有运行插件 - 只是JUnit测试。



当我运行plugin-2(使用产品配置)并实例化 MyClass ,本地库加载正常,但是当 MyClass 实例化时,我会得到一个 UnsatisifiedLinkError code> MyLibraryClass 。在这种情况下,我相信该库正在加载,基于我使用发布如何获取加载的JNI库的列表?



注意:我正在使用Eclipse 3.6.1。



这是一个代码示例,显示了我正在尝试的内容:
package com.mylibrary;

  import com.external_library.MyLibraryClass; 


public class MyClass {


public static void loadLibrary(){
//在MANIFEST.MF中没有Bundle-NativeCode get
//java.lang.UnsatisfiedLinkError:no mylibrary_java in java.library.path
System.loadLibrary(mylibrary_java); //加载libmylibrary_java.so。

//从JUnit测试
//当我运行插件时,我得到一个UnsatisfiedLinkError:
//java.lang.UnsatisfiedLinkError:
/ / com.external_library.MyLibrary_javaJNI.new_MyLibraryClass__SWIG_3()J
MyLibraryClass instance = new MyLibraryClass();

}
}


解决方案

我已经复制了你的设置,我得到了同样的例外。



可以通过以下方式解决问题:





  • 将Bundle-NativeCode指令添加到plugin-1的Manifest

  • 将静态构造函数中的库加载插件1的Activator(你可以写一个并添加到插件)



其他一些可能的错误来源: / strong>
请注意,对于具有本机绑定的任何类,请注意,包路径,类名和方法签名不应该更改。否则JNI将无法找到本机对象,并且您会收到一个UnsatisfiedLinkError。在您的导入指令中,您指定了以下类名com.external_library.MyLibraryClass,但您的错误消息具有不同的类名com.external_library.MyLibrary_javaJNI。检查这些错误来源。



其他一些说明:
与JUnit插件测试相反的JUnit测试不会启动OSGi环境。因此,您有一个普通的JUnit测试的普通Java应用程序。如果您的本地库和您的应用程序包含在同一个文件夹(顶层)中,则本地库将自动在Windows上找到。如果在UNIX系统上也是如此,这将是您的JUnit测试成功的原因。如果它位于不同的文件夹中,则必须为普通Java应用程序指定Java库路径。



MrMas编辑:
修改plugin-2它不依赖于plugin-1,将.jar文件添加到plugin-2。


  1. 将.jar文件复制到plugin- 2。我将它放在与.so相同的目录中。

  2. 通过以下方式将jar添加到项目中:Project-> Properties-> Libraries-> Add Jar

  3. 通过plugin.xml-> Runtime-> ClassPath部分添加jar到类路径 - >添加

  4. 从Jar导出包(如果下载插件需要) )

  5. 从plugin.xml->依赖选项卡中删除plugin-1的依赖性

现在,您可以使用System.loadLibrary加载库,并使用插件和另一个插件中的类。



我选择不修改plugin-1,因为它是从现有的jar创建的插件,我无法发现如何添加一个Activator。我选择了将.jar添加到plugin-2的路径。请参阅将jar添加到Eclipse PlugIn 以进行其他讨论。


I have two Eclipse plugins:

  • plugin-1: provides a package in .jar to other plugins. (a Java Wrapper for a C++ library) This plugin was created by clicking File->New->Other->Plug-in from Existing JAR Archives.

  • plugin-2: has the native library .so for plugin-1 (Bundle-NativeCode directive is in MANIFEST.MF) and instantiates a class from plugin-1

(I actually tried putting the .so in plugin-1, but I cannot seem to load the library, even with the Bundle-NativeCode directive in the plugin-1 MANIFEST.MF, outside of the plugin project that contains the .so, so I guess I have to bundle the .so with any plugin that uses plugin-1.)

I am running a JUnit tests from plugin-2 which instantiates MyClass from plugin-2 which, in turn, instantiates MyLibraryClass from plugin-1. MyClass successfully loads the native library and instantiates MyLibraryClass without an UnsatisfiedLinkError or other exception being thrown from either the loading of the native library or from instantiating MyLibraryClass. I am not running a plugin in this case -- just the JUnit tests.

When I run plugin-2 (using a product configuration) and instantiate MyClass, the native library loads fine but I get an UnsatisifiedLinkError when MyClass instantiates MyLibraryClass. In this case, I believe the library is being loaded based on the output I get from using the class described in the posting How do I get a list of JNI libraries which are loaded?

NOTE: I'm using Eclipse 3.6.1.

Here is a code sample that shows the essence of what I'm trying to do: package com.mylibrary;

import com.external_library.MyLibraryClass;


public class MyClass {


    public static void loadLibrary() {
      // Without Bundle-NativeCode in MANIFEST.MF I get 
      // "java.lang.UnsatisfiedLinkError: no mylibrary_java in java.library.path"
      System.loadLibrary("mylibrary_java"); // Loads libmylibrary_java.so. 

      // Works fine from JUnit Test
      // When I run the plugin, I get an UnsatisfiedLinkError:
      // "java.lang.UnsatisfiedLinkError: 
      // com.external_library.MyLibrary_javaJNI.new_MyLibraryClass__SWIG_3()J"
      MyLibraryClass instance = new MyLibraryClass(); 

    }
}

解决方案

I have replicated your setup and I get the same exception.

The problem could be solved by:

  • add the native library to plugin-1
  • add the Bundle-NativeCode directive to plugin-1's Manifest
  • load the library in the static constructor of plugins-1's Activator (you can write one and add it to the plugin)

Some other possible sources of errors: Be aware that the package path, the class name and the method signatures should never be changed for any class with native bindings. Otherwise JNI would not be able to find the native counterpart and you get an UnsatisfiedLinkError. In your import directive you specified the following classname com.external_library.MyLibraryClass, but your error message has a different classname com.external_library.MyLibrary_javaJNI. Check for these sources of errors.

Some additional explanations: A JUnit test in contrast to an JUnit plugin test starts no OSGi environment. Therefore you have a plain Java application with an ordinary JUnit test. If your native lib and your application are contained in the same folder (top level) the native lib will be automatically found on windows. If that is also true on UNIX systems, this would be an explanation why your JUnit test is successful. If it lies in a different folder, you have to specify the Java Library Path for an ordinary Java application.

EDIT by MrMas: Modify plugin-2 so it doesn't depend on plugin-1 by adding the .jar file to plugin-2.

  1. Copy the .jar file into plugin-2. I put it in the same directory as the .so.
  2. Add the jar to the project via: Project->Properties->Libraries->Add Jar
  3. Add the jar to the class path via plugin.xml->Runtime->ClassPath section->Add
  4. Export the packages from the Jar (if they're needed by downstream plugins)
  5. Remove the dependence of plugin-1 from the plugin.xml->dependencies tab

Now you can load the library with a System.loadLibrary and use the classes from within the plugin and from another plugin.

I chose not to modify plugin-1 because it was created as a plugin from an existing jar to which I couldn't discover how to add an Activator. I instead chose the path of adding the .jar to plugin-2. See Adding jars to a Eclipse PlugIn for additional discussion.

这篇关于不满意的链接错误:库加载但我仍然收到链接错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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