web-dev-qa-db-ja.com

テスト用にJava.library.pathを設定します

テストの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_を設定するにはどうすればよいですか?

9
Michael Ivko

Sachin Handiekarのコメントのように、この問題は、Ideaが実行されている環境でLD_LIBRARY_PATHを設定することで解決されます。 (ただし、何らかの理由で、アイデアの設定にはありません。)

0
Michael Ivko

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で実行されるため、行っている変更は考慮されません。

3
Tunaki

テストを実行するために新しい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>
2
ajschmidt

「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テスト」内での実行の両方で取得されます。

0
Gareth Randall