设置java.library.path以测试

时间:2016-02-12 15:17:04

标签: java maven testing java-native-interface

其中一个测试使用本机库:

System.loadLibrary("mylib");

libmylib.so位于/usr/local/lib,因此我在配置VM选项中添加此目录:-Djava.library.path=/usr/local/lib

但是,当我使用Maven运行测试时,此行会抛出UnsatisfiedLinkError

  

mylib

中没有java.library.path

在没有此选项的情况下调用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任务没有影响。

所以我尝试在Maven的VM选项中设置库路径:设置 - >构建,执行,部署 - >构建工具 - > Maven-> Runner-> 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

4 个答案:

答案 0 :(得分:3)

您可以add system properties to the maven-surefire-pluginsystemPropertyVariables属性的帮助下运行测试:

<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中运行,因此不会考虑您正在进行的修改。

答案 1 :(得分:2)

您很可能遇到此问题,因为您正在使用像surefire或failsafe这样的Maven插件,它会启动一个新的JVM来运行您的测试并且您的启动配置不会被传递。此外,您可能还需要在新进程的命令行上设置“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 :(得分:0)

与Sachin Handiekar的评论一样,通过在运行Idea的环境中设置LD_LIBRARY_PATH来解决该问题。 (但出于某种原因,不是在Idea设置中。)

答案 3 :(得分:0)

未通过Intellij&#34;传递给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

这样做不方便成为一个自定义的“每用户”操作,但它似乎并不比每个用户&#34;每个用户&#34;在IDE中。

现在,本地库在Intellij中的单个单元测试运行期间以及在&#34; maven test&#34;中的运行中被选取。