テストの1つは、ネイティブライブラリを使用します。
_System.loadLibrary("mylib");
_
_libmylib.so
_は_/usr/local/lib
_にあるので、このディレクトリを構成に追加しますVM options:_-Djava.library.path=/usr/local/lib
_
ただし、Mavenでテストを実行すると、この行はUnsatisfiedLinkError
をスローします。
_
Java.library.path
_にmylib
がありません
Javaは、このオプションなしで呼び出されます。
_/usr/lib/jvm/Java-8-Oracle/bin/Java -Dmaven.home=/opt/idea/plugins/maven/lib/maven3 -Dclassworlds.conf=/opt/idea/plugins/maven/lib/maven3/bin/m2.conf -Didea.launcher.port=7538 -Didea.launcher.bin.path=/opt/idea/bin -Dfile.encoding=UTF-8 -classpath /opt/idea/plugins/maven/lib/maven3/boot/plexus-classworlds-2.4.jar:/opt/idea/lib/idea_rt.jar com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=15.0.3 test
_
例外をキャッチするときにSystem.getProperty("Java.library.path")
を出力すると、_/opt/idea/bin::/usr/Java/packages/lib/AMD64:/usr/lib64:/lib64:/lib:/usr/lib
_が得られます。どうやらVM実行構成のオプションは、Mavenタスクに影響を与えません。
だから私はVM Mavenのオプション:設定->ビルド、実行、展開->ビルドツール-> Maven->ランナー-> VMオプションでライブラリパスを設定しようとしました=。このオプションは、Java呼び出しコマンド:
_/usr/lib/jvm/Java-8-Oracle/bin/Java -Djava.library.path=/usr/local/lib -Dmaven.home=/opt/idea/plugins/maven/lib/maven3 -Dclassworlds.conf=/opt/idea/plugins/maven/lib/maven3/bin/m2.conf -Didea.launcher.port=7539 -Didea.launcher.bin.path=/opt/idea/bin -Dfile.encoding=UTF-8 -classpath /opt/idea/plugins/maven/lib/maven3/boot/plexus-classworlds-2.4.jar:/opt/idea/lib/idea_rt.jar com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=15.0.3 test
_
ただし、Javaがこのオプションで呼び出されるようになりましたが、ライブラリのロードに失敗し、System.getProperty("Java.library.path")
にも同じものが含まれています!
Mavenで呼び出されるテストに_Java.library.path
_を設定するにはどうすればよいですか?
Sachin Handiekarのコメントのように、この問題は、Ideaが実行されている環境でLD_LIBRARY_PATHを設定することで解決されます。 (ただし、何らかの理由で、アイデアの設定にはありません。)
systemPropertyVariables
属性を使用してテストを実行しているときに、 システムプロパティをmaven-surefire-plugin
に追加できます。
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<systemPropertyVariables>
<propertyName>Java.library.path</propertyName>
<buildDirectory>/usr/local/lib</buildDirectory>
</systemPropertyVariables>
</configuration>
</plugin>
これにより、テストの実行時にJava.library.path
がシステムプロパティとして追加されます。テストはフォークされたVMで実行されるため、行っている変更は考慮されません。
テストを実行するために新しいJVMを起動するsurefireやfailsafeなどのMavenプラグインを使用していて、起動構成が渡されないため、この問題が発生する可能性があります。また、起動時にネイティブライブラリとそのすべての依存関係をリンクできるように、新しいプロセスのコマンドラインで「Java.library.path」を設定する必要もあります。 'systemPropertyVariables'を使用した場合、同じ効果はありませんが、運が良ければ機能する可能性があります。これが私のために働いているプラグイン設定の例です:
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19</version>
<executions>
<execution>
<id>my-external-tests</id>
<goals>
...
</goals>
<configuration>
<argLine>-Djava.library.path=/usr/local/lib</argLine>
<groups>com.myCompany.ExternalTest</groups>
<includes>
<include>**/*Suite.Java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
「IntellijによってMavenに渡されないネイティブライブラリパス」の問題の解決策:
JVMによってすでに検索されているローカルディレクトリを利用できることがわかりました。
まず、JUnitテストまたはライブコード中にSystem.outメッセージを使用してJava.library.pathを出力します。
私のMacでは、次のようになります。
/Users/gareth/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/Java:.
このライブラリパスの最初の部分は、JVMが最初にユーザーのローカルディレクトリを検索するため、問題を回避する方法を提供します(/Users/gareth/Library/Java/Extensions
)そしてjnilibファイルをここにシンボリックリンクできます:
そう:
$ mkdir -p /Users/gareth/Library/Java/Extensions
$ cd /Users/gareth/Library/Java/Extensions
$ ln -s /Users/gareth/Applications/IBM/ILOG/CPLEX_Studio_Community127/cplex/bin/x86-64_osx/libcplex1270.jnilib libcplex1270.jnilib
これには、カスタムの「ユーザーごと」の操作であるという不便がありますが、IDEで「ユーザーごと」に実行するよりも悪いことではないようです。
これで、ネイティブライブラリは、Intellij内での個々の単体テストの実行中と、「mavenテスト」内での実行の両方で取得されます。