Set java.library.path for testing
Solution 1
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.)
Solution 2
You can add system properties to the maven-surefire-plugin
when the tests are running with the help of the systemPropertyVariables
attribute:
<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.
Solution 3
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:
<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>
Related videos on Youtube
Michael Ivko
Updated on September 14, 2022Comments
-
Michael Ivko over 1 year
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
However, when I run tests with Maven, this line throws
UnsatisfiedLinkError
:no
mylib
injava.library.path
Java is invoked without this option:
/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.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:
/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!How to set
java.library.path
for tests invoked with Maven?-
Michael Ivko about 8 yearsYes, setting LD_LIBRARY_PATH actually helps!
-
SachinHave you tried using the LD_LIBRARY_PATH env. variable ? Also have you tried to use System.load("/usr/local/lib/libmylib.so"); ?
-
-
Michael Ivko about 8 yearsThis probably would help, but I'd avoid it because it make pom.xml dependent on peculiarities of build environment.
-
Tunaki about 8 years@MichaelIvko But the POM should be self-contained. So it should be dependent on peculiarities of the build environement. The problem with your solution is that it entirely depends on a 3rd party IntelliJ to hold the info. If you were to build this on the command line or on a CI server, it wouldn't work anymore, which goes against the principle of using Maven.
-
Tunaki about 8 yearsThe problem with that is that it makes your build dependant of IntelliJ when it shouldn't be. Everything should be in the POM so that the project can be build elsewhere. So with this solution, it won't work on the command line for example.
-
Michael Ivko about 8 yearsAdding a dependency on files in a specified external directory does not make POM self-contained. The fact that the library is not included in explicit dependencies is probably against maven principles, but I needed to build the project as it is.
-
Dawood ibn Kareem about 6 yearsYou really shouldn't do this. The whole idea with maven is that the pom file is supposed to contain all the information you need to build, and that the build shouldn't rely on IntelliJ, or on any configuration that exists outside of the pom file. This might work locally on your computer, but it won't help if you're working in a team, or if you have any kind of continuous integration in your environment.
-
Heri over 3 yearsVersion 3.0 of maven-surefire-plugin shows warning:
java.library.path cannot be set as system property, use <argLine> ...
(see example in ajschmidt's answer) -
Heri over 3 yearsA note to the location of the library: I think a library on which a project is dependent should be part of the Workspace (SCM), or provided by a well defined repository (version controlled) during build process. Then you can work with a relative path. And you are sure that your tests use the same binaries as the productive server will do.
-
dimirsen Z over 3 yearsYou posted a copy of config from the manual. It should be adapted this way: <systemPropertyVariables> <java.library.path>/usr/local/lib</java.library.path> <buildDirectory>${project.build.directory</buildDirectory> </systemPropertyVariables>