2011-05-14 10 views
1

[最終解決策は、コメントに受け入れられた回答に記載されています。 bmargulies]Java - JNAおよび共有ライブラリ、Linuxでの.jarからの起動時のUnsatisfiedLinkError

のおかげでちょっと人々は、

私は非常に奇妙なエラーを持っていると私はその理由を把握することはできません。ここではセットアップがあります:私はプラットフォームに依存しない音楽プレーヤーをJavaで構築しています。ネイティブのサウンドライブラリとして、irrKlangエンジン(http://www.ambiera.com/irrklang/)を使用しています。これは、それぞれWindows、Linux、MacOS用の共有ライブラリのセットとして提供されています。これらのライブラリはC++で書かれているので、必要なオペレーティングシステムごとにコンパイルされたラッパー(C++でもextern "C"などを使用)として共有ライブラリを構築しました。 私は今、JNAからそのラッパーを使います。私はEclipseの、プロジェクトのメインフォルダ(現在の作業ディレクトリ)に必要なすべてのライブラリレジストを使用しています。ここで問題が起こる:私はEclipseからJavaアプリケーションを実行し、Windowsの.jarをプロジェクトのメインフォルダに作成して実行すると問題は起こらないが、すべてうまくいく。私は.jarファイルに(!通常作業)アプリケーションをパックするときしかし、特にLinux上で、私は次のエラーを取得する:

Exception in thread "main" java.lang.reflect.InvocationTargetException 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:616) 
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58) 
Caused by: java.lang.UnsatisfiedLinkError: Unable to load library 'IrrklangWrapper': libIrrKlang.so: cannot open shared object file: No such file or directory 
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163) 
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236) 
at com.sun.jna.Library$Handler.<init>(Library.java:140) 
at com.sun.jna.Native.loadLibrary(Native.java:379) 
at com.sun.jna.Native.loadLibrary(Native.java:364) 
at Demo.<init>(Demo.java:29) 
at Demo.main(Demo.java:55) 
... 5 more 

は「IrrKlangWrapper」は、私自身の共有ライブラリです「libIrrKlang.so」ライブラリですそれによって包まれる。 JNAは私の図書館を見つけることができますが、図書館は図書館を見つけることができません。奇妙な!特に私がプロジェクトを直接開始すると(.jarを構築せずに)これが起こらないためです。

C++で書かれたコードもありますので、問題の原因はそこにありますが、含まれているメソッドが呼び出される前にエラーが発生しているとは思いますが

#include <iostream> 
#include <stdio.h> 
#include <irrKlang.h> 
#include <sys/stat.h> 
#include <string> 
#include <unistd.h> 
using namespace std; 

extern "C" { 

int func(char *path) { 
    cout << path << endl; 

    irrklang::ISoundEngine* engine = irrklang::createIrrKlangDevice(); 
    engine->loadPlugins("./"); 
    cout << engine->getDriverName() << endl; 
    engine->play2D(path); 
    //Endless loop for testing. TODO: Remove 
    while (true) { 
    } 
    engine->drop(); 

    return 0; 
} 
} 

誰でもこの問題を解決する方法がありますか?私のアプリケーションはプラットフォームに依存しないため、共有ライブラリを特定のフォルダにコピーすることはできません。アプリケーションの(サブ)フォルダに置く必要があります。あなたは第2の共有というライブラリを含むディレクトリが含まれるようにLD_LIBRARY_PATHを設定する必要がありますLinuxでは、事前に

おかげで、

アンドレ

答えて

3

この要件は回避するのが非常に難しいです。 LD_LIBRARY_PATHは、Javaプロセスの開始時にld.soによってのみ読み取られます。後で追加することはできません。

大きな共有ライブラリを作る必要があります。これは、あなたの依存関係の.aバージョンを見つけてそこに組み込むことを意味します。

+0

私はすでにそれがそういうものかもしれないと思っていました。どうすればC++コードからこれを行うことができますか?そして:なぜ直接実行されたときに動作していますか? –

+0

実際にはlinux *上で「直接」*動作しますか? – bmargulies

+0

です。 Eclipseのそれを開始すると、プロジェクトのメインフォルダ内の共有ライブラリが使用されます。 –

関連する問題