fail to load a native library using activator (Play Framework)
-
I'm trying to load a native library in my Play 2.4.x application. I have written a simple test that works fine both in the IDE (IntelliJ) and in SBT. In both case I'm setting the java.library.path to get the tests to run. In the IDE, I set -Djava.library.path=$USER_HOME$/dev/lindoapi/bin/linux64 in the test run configuration. As per the sbt documentation, my build.sbt is forking the JVM and setting the java.library.path. javaOptions += "-Djava.library.path=/home/aczerwon/dev/lindoapi/bin/linux64" fork := true The following test passes just fine in both the IDE and from activator test. class LindoApiSpec extends Specification { System.loadLibrary("lindojni") "The Lindo API" should { "have a valid license" in { val lindo = new LindoEnvironment() lindo.apiVerion() must beSuccessfulTry.withValue("LINDO API Version 9.0.2120.225") } } When outside of the testing context, I load the native library in Play's startup lifecycle. object Global extends GlobalSettings { override def beforeStart(app: Application) = { System.loadLibrary("lindojni") } } When I call that same method from the webapi (activator ~run), I'm getting an UnsatisfiedLinkError error. 1) Error injecting constructor, java.lang.UnsatisfiedLinkError: no lindojni in java.library.path at play.api.GlobalPlugin.<init>(GlobalSettings.scala:262) at play.api.GlobalPlugin.class(GlobalSettings.scala:262) while locating play.api.GlobalPlugin The web api looks like this: class OptimizationApi extends Controller { def version() = Action { val lindo = new LindoEnvironment() lindo.apiVerion() match { case Success(version) => Ok(version) case Failure(e) => BadRequest(e.getMessage) } } } I assumed that my build.sbt would fork the JVM and set the java.library.path for both test and run contexts. Any clues as to what I'm doing wrong? New Information When I start activator -Djava.library.path=$USER_HOME$/dev/lindoapi/bin/linux64 or set JAVA_OPTS, the call to System.loadLibrary(...) in the startup lifecycle passes. I still get the UnsatisfiedLinkError, but it happens later when I make a call to the native library via JNI. Very strange.
-
Answer:
I found a solution to the issue https://github.com/playframework/playframework/issues/2212#issuecomment-82024667. The native library and its java counterpart must be in the same class loader. Create a class similar to: public final class PlayNativeLibraryLoader { public static void load(String library) { System.load(library); } } And now you can use it in the Play startup lifecycle. object Global extends GlobalSettings { override def beforeStart(app: Application) = { PlayNativeLibraryLoader.load(app.getFile("./lib/lindoapi/linux64/liblindojni.so").getPath) Logger.info("Lindo native library loaded") } }
andyczerwonka at Stack Overflow Visit the source
Related Q & A:
- How to change folder properties inside a sharepoint library?Best solution by SharePoint
- How to hybrid Mysql and MongoDB in Play framework?Best solution by Stack Overflow
- How to return multiple objects of a specific library in R?Best solution by Stack Overflow
- How to make a native chat app in Swift?Best solution by udemy.com
- Can I play my PS3 games on my PSP using remote play?Best solution by Yahoo! Answers
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.