设置 java.library.path 进行测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35366035/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set java.library.path for testing
提问by Michael Ivko
One of the tests uses a native library:
其中一项测试使用本机库:
System.loadLibrary("mylib");
libmylib.so
is located in /usr/local/lib
, So I add this directory in configuration VM options: -Djava.library.path=/usr/local/lib
libmylib.so
位于/usr/local/lib
,所以我在配置VM选项中添加了这个目录:-Djava.library.path=/usr/local/lib
However, when I run tests with Maven, this line throws UnsatisfiedLinkError
:
但是,当我使用 Maven 运行测试时,这一行会抛出UnsatisfiedLinkError
:
no
mylib
injava.library.path
没有
mylib
在java.library.path
Java is invoked without this option:
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
Printing System.getProperty("java.library.path")
when catching the exception gives /opt/idea/bin::/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
. Apparently VM options from run configuration have no effect on maven tasks.
System.getProperty("java.library.path")
捕获异常时打印给出/opt/idea/bin::/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
. 显然,运行配置中的 VM 选项对 Maven 任务没有影响。
So I tried to set library path in VM options for Maven: Settings->Build, Execution, Deployment->Build Tools->Maven->Runner->VM options. This option has the effect on java invocation command:
所以我尝试在 Maven 的 VM 选项中设置库路径:Settings->Build, Execution, Deployment->Build Tools->Maven->Runner->VM options。此选项对 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
But even though Java is now invoked with this option, it still fails to load the library, and System.getProperty("java.library.path")
still contains the same thing!
但是即使现在使用此选项调用 Java,它仍然无法加载库,并且System.getProperty("java.library.path")
仍然包含相同的内容!
How to set java.library.path
for tests invoked with Maven?
如何设置java.library.path
使用 Maven 调用的测试?
采纳答案by Michael Ivko
As in Sachin Handiekar's comment, the issue is solved by setting LD_LIBRARY_PATH in the environment in which Idea is run. (But not in Idea settings, for some reason.)
在 Sachin Handiekar 的评论中,通过在运行 Idea 的环境中设置 LD_LIBRARY_PATH 来解决该问题。(但出于某种原因,不在 Idea 设置中。)
回答by Tunaki
You can add system properties to the maven-surefire-plugin
when the tests are running with the help of the systemPropertyVariables
attribute:
您可以在以下属性maven-surefire-plugin
的帮助下将系统属性添加到测试运行时systemPropertyVariables
:
<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>
This will add the java.library.path
as a system property when the tests are ran. The modification you are making is not taken into account since the tests are ran in a forked VM.
这将java.library.path
在运行测试时添加作为系统属性。由于测试是在分叉的 VM 中运行的,因此不会考虑您所做的修改。
回答by ajschmidt
You are most likely encountering this problem because you are using a Maven plugin like surefire or failsafe which launches a new JVM to run your tests and your launch configuration is not getting passed on. Also, you probably also need to set the 'java.library.path' on the command line of the new process so that the native library and all of its dependencies can be linked at startup. If you use 'systemPropertyVariables' it won't have the same effect, but might work if you lucky. Here is an example plugin configuration that is working for me:
您很可能会遇到这个问题,因为您使用的是 Maven 插件,如 surefire 或 failsafe,它启动一个新的 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>
回答by Gareth Randall
Solution to the "native library path not passed through to Maven by Intellij" problem:
“本机库路径未通过 Intellij 传递到 Maven”问题的解决方案:
I've found that you can make use of the local directory that is already searched by the JVM.
我发现您可以使用 JVM 已经搜索过的本地目录。
First, print your java.library.path using a System.out message during your Junit test or live code.
首先,在您的 Junit 测试或实时代码期间使用 System.out 消息打印您的 java.library.path。
On my Mac I get the following:
在我的 Mac 上,我得到以下信息:
/Users/gareth/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
The first part of this library path offers us a way out of the problem, because the JVM searches the user's local directory first ( /Users/gareth/Library/Java/Extensions
) and we can symlink the jnilib file in to here:
这个库路径的第一部分为我们提供了解决问题的方法,因为 JVM 首先搜索用户的本地目录 ( /Users/gareth/Library/Java/Extensions
),我们可以将 jnilib 文件符号链接到这里:
So:
所以:
$ 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
This has the inconvenience of being a custom “per user” operation, but it seems no worse than doing it "per user" in the IDE.
这有作为自定义“每个用户”操作的不便,但似乎并不比在 IDE 中“每个用户”执行更糟糕。
Now the native library is picked up both during individual unit test runs within Intellij, and from runs within "maven test".
现在,在 Intellij 中的单个单元测试运行期间以及从“maven 测试”中的运行中获取本机库。