Question

OSGi ne peut pas trouver mon fichier DLL, et je ne peux pas à comprendre pourquoi.

Actuellement, j'ai le fichier DLL (de foo.dll) à la racine de mon paquet, je l'ai aussi essayé d'avoir dans un répertoire libs.

Le Manifeste pour le paquet en question ressemble à ceci:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: foobundle
Bundle-SymbolicName: com.foo.bar
Bundle-Version: 1.0.0
Bundle-Vendor: me
Import-Package: com.sun.jna,
 com.sun.jna.ptr,
 com.sun.jna.win32
Export-Package: com.foo.bar
Bundle-NativeCode: foo.dll;
 osname=WindowsXP;
 processor=x86

Alors dans mon interface JNA je joue un loadLibrary (selon la documentation):

public interface MyFooInterface extends com.sun.jna.Library{
    static final MyFooInterface INSTANCE = (MyFooInterface)com.sun.jna.Native.loadLibrary("foo", MyFooInterface .class);

    // specific interface defs here...
}

Ensuite, dans une autre classe que je tente d'utiliser l'interface JNA

// ...code
int var = MyFooInterface.INSTANCE.bar();
// ...more code

Je JNA fourni par un autre paquet (qui exporte com.sun.jna et les autres emballages importés ci-dessus), mais ont aussi essayé de l'emballage avec le faisceau défini ici (et ajouté au classpath dans ce cas, etc. ).

J'ai aussi essayé spécifier Bundle-NativeCode: /foo.dll.

De plus d'intérêt, ce sont les propriétés OSGi pertinentes (que je tiré à l'aide getprop)

org.osgi.framework.os.name=WindowsXP
org.osgi.framework.processor=x86

Même après tout cela (et avec tous les essais que j'ai fait) je finis toujours avec l'erreur suivante (et une trace de pile non représentée):

java.lang.UnsatisfiedLinkError: Unable to load library 'foo': The specified module could not be found.

... donc ce que je suis absent?

Modifier :. Je tiens également à noter que je l'ai testé et eu du succès le code d'interface JNA et la DLL qu'il parle dans le cadre d'un programme de test JUnit

Edit 2 : L'ajout de ce code à la classe qui vous appelle la bibliothèque semble permettre à la JNA de trouver la bibliothèque (quand Native.loadLibrary est appelée plus tard). Il semble que je devrais être en mesure d'éviter cet appel en fonction de la directive Bundle-NativeCode dans le manifeste. De toute évidence, une fois la bibliothèque est chargée Native.loadLibrary saisit l'instance existante de celui-ci, mais je préférerais ne pas dépendre de cette tactique très spécifique ordre.

static{
    System.loadLibrary("foo");
}
Était-ce utile?

La solution

Le problème est l'appel spécialisé JNA loadLibrary, qui ne connaît pas OSGi. Lorsque vous appelez loadLibrary d'un faisceau de OSGi, il utilisera le classloader OSGi (qui est au courant bundle), pour trouver la DLL est, et dans ce cas, l'extraire hors du faisceau et de le rendre chargeable via le System.loadLibrary () appel contre un endroit précis.

Étant donné que cette JNA semble être (a) pas OSGi au courant, et (b) superflu, pourquoi ne pas simplement utiliser System.loadLibrary () à la place?

Si vous devez écrire à la fois, puis effectuer une méthode System.loadLibrary () dans le début () du paquet dans le BundleActivator, qui apportera la bibliothèque native dans (vous voulez probablement faire en sorte que si elle ne peut pas être chargé , le faisceau ne peut pas être démarré en tout cas).

Autres conseils

En regardant la documentation de la JNA, il est écrit:

  • votre bibliothèque cible disponible à votre programme Java. Il y a deux façons de faire ça:
    • La méthode préférée consiste à définir la propriété système jna.library.path sur le chemin à votre bibliothèque cible. Cette propriété est similaire à java.library.path mais applique uniquement aux bibliothèques chargées par la JNA.
    • Modifier la variable d'environnement d'accès à la bibliothèque appropriée avant de lancer la machine virtuelle. Ceci est PATH sous Windows, LD_LIBRARY_PATH sous Linux, et DYLD_LIBRARY_PATH sur OSX.

Donc, pour contourner cette lacune, vous pouvez résoudre le chemin absolu de la bibliothèque et de la charge que.

En supposant que son chargeur de classe standard de Eclipse, vous pouvez le faire ClassLoader.findLibrary() qui devrait trouver la bibliothèque locale dans le paquet.

Je vous suggère d'essayer d'emballer le dll comme un pot:

jar cvf foo.dll.jar foo.dll

et la charge du pot comme lib régulier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top