为测试设置java.library.path
其中一个测试使用本机库:为测试设置java.library.path,java,maven,testing,java-native-interface,Java,Maven,Testing,Java Native Interface,其中一个测试使用本机库: System.loadLibrary("mylib"); libmylib.so位于/usr/local/lib中,因此我在配置VM选项中添加了此目录:-Djava.library.path=/usr/local/lib 但是,当我使用Maven运行测试时,此行抛出未满足的linkerror: java.library.path中没有mylib 调用Java时不使用此选项: /usr/lib/jvm/java-8-oracle/bin/java -Dmaven.hom
System.loadLibrary("mylib");
libmylib.so
位于/usr/local/lib
中,因此我在配置VM选项中添加了此目录:-Djava.library.path=/usr/local/lib
但是,当我使用Maven运行测试时,此行抛出未满足的linkerror
:
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
?当测试在属性的帮助下运行时,您可以:
maven surefire插件
2.19.1
java.library.path
/usr/local/lib
这将在运行测试时添加java.library.path
作为系统属性。您正在进行的修改没有被考虑在内,因为测试是在一个分叉的VM中运行的。正如Sachin Handiekar的评论中所述,通过在运行Idea的环境中设置LD_LIBRARY_路径可以解决此问题。(但由于某些原因,不是在Idea设置中。)解决“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文件符号链接到这里:
因此:
这会给自定义“每用户”操作带来不便,但它似乎并不比在IDE中“每用户”操作更糟糕
现在,在Intellij中的单个单元测试运行期间以及在“maven test”中的运行期间,都会获取本机库。您很可能会遇到这个问题,因为您使用的是像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>
maven故障保护插件
2.19
我的外部测试
...
-Djava.library.path=/usr/local/lib
com.myCompany.ExternalTest
**/*Suite.java
您可以在maven surefire插件中这样配置VM选项
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Djava.library.path=/usr/local/lib</argLine>
</configuration>
....
</plugin>
org.apache.maven.plugins
您是否尝试过使用LD_LIBRARY_PATH env。变量您还尝试过使用System.load(“/usr/local/lib/libmylib.so”)?是的,设置LD_LIBRARY_路径实际上很有帮助!这可能会有帮助,但我会避免它,因为它使pom.xml依赖于构建环境的特性。@MichaelIvko但pom应该是自包含的。所以它应该取决于构建环境的特性。您的解决方案的问题在于,它完全依赖于第三方IntelliJ来保存信息。如果您要在命令行或CI服务器上构建它,它将不再工作,这违反了使用Maven的原则。添加对指定外部目录中文件的依赖关系不会使POM自包含。库没有包含在显式依赖项中这一事实可能违反了maven原则,但我需要按原样构建项目。maven surefire插件的3.0版显示了警告:java.library.path不能设置为系统属性,请使用…
(参见ajschmidt回答中的示例)关于库位置的说明:我认为项目依赖的库应该是工作区(SCM)的一部分,或者在构建过程中由定义良好的存储库(版本控制)提供。然后可以使用相对路径。而且您确信您的测试使用的二进制文件与生产服务器使用的二进制文件相同。问题是,这会使您的构建依赖于IntelliJ,而实际上它不应该依赖IntelliJ。所有东西都应该在POM中,以便项目可以在其他地方构建。因此,有了这个解决方案,它就不能在命令行上工作,例如,你真的不应该这样做。maven的整个想法是pom文件应该包含您需要构建的所有信息,并且构建不应该依赖IntelliJ或pom文件之外的任何配置。这可能在您的计算机上本地工作,但如果您是在团队中工作,或者您的环境中有任何类型的持续集成,这都不会有帮助。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Djava.library.path=/usr/local/lib</argLine>
</configuration>
....
</plugin>