質問: ### したいこと jarファイルをダブルクリックすると起動できるアプリケーションを作ろうと考えています。環境はeclipse 4.4 Lunaです。 ### 発生している問題 コード中に使用したライブラリ(具体的にはLWJGLというライブラリのver2.9.3)がnative(.so/.dll/.dylib 等)に依存しており、Eclipseから直接「実行可能Jar」を書き出して実行すると、UnsatisfiedLinkErrorが発生します。 ライブラリがnativeを読み込めていないので、生成したJarの中にnativeを入れればいいのはなんとなく分かっているものの、nativeを読み込ませる為のMANIFEST.MFの書き方が分かっていない為、困っております。 なお当然ですがEclipse上では動作しています。 ### 試したこと ・JarSpliceを使ってJarやNativesをまとめてみる →ライブラリのjar追加時にエラーが出て生成に失敗 ・MANIFEST.MFにBundle-NativeCodeなるものを追記してみる →OSごとに違うnativeのファイルを読み込む方法が分からず断念 (MANIFEST.MF自体にOSごとの振り分けを記述できるようなサイトも見たが、上手く動作せず...) ・Google先生に聞く →聞き続けて1週間半程たちましたが、いい参考文献に出会えずにいますのでteratailで初質問させていただいてます。 --- 恐れ入りますが、ご経験のある方やご存知の方いらっしゃいましたら、回答の程よろしくお願いいたします。 お読みいただきありがとうございました。
回答: そもそもJNIをまともに使った経験がないのですが、回答がつかないようなのと、興味があったので調べてみました。 * jarからnative libraryをロード 探してみるとstackoverflow: How to bundle a native library and a JNI library inside a JAR?というのがあり、回答にgithub: native-utilsが薦められていたので、中身をみてみると、jarの中からネイティブライブラリーを取り出してそれを一時ファイルへ書き出しSystem.loadするという内容でした。 素直な実装とは思いますが「これでいいのかぁ」と思いました。実装は非常にシンプルです。 * platform判定 複数のプラットフォーム向けのjarにしたいとのことなので、上記の実装を使うならプラットフォームをあらかじめ判定する必要が出てきます。同様にstackoverflowにWindowsとLinuxを判定する例が載っています。apache commons langを利用するようですね。 また、自分はJavaFXのツールであるScene Builderでプラットフォームの判定をしているコードを見たことがあるので調べてみました。ソースは最新ではないですが以下のようなコードが見つかりました。 SceneBuilderは元々OracleがJDKと一緒に配布していたものであり下記はOracleの実装なのかも知れません(なお、現在はScene BuilderはOracleの手を離れOSSになってます)。しかし、実装の妥当性はご自分でもよく確認した方がよいと思います。 ``` private static final String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT); public static final boolean IS_LINUX = osName.contains("linux"); public static final boolean IS_MAC = osName.contains("mac"); public static final boolean IS_WINDOWS = osName.contains("windows"); ```