jar unable to locate audio files - java

So I'm writing a program in Java that must be able to play wav files. It works perfectly when run from within Intellij, but when I run it from the jar it crashes immediately when it tries to retrieve the sound files and returns this error:
Unable to create from inputstream, Stream closed
Exception in thread "main" java.lang.NullPointerException
Here is the code that I'm using to retrieve the sound files:
protected int loadSound(String file) {
int data = AL10.alGenBuffers(); //Create new buffer object
buffers.add(data); //Store buffer ID in array list
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream filePath = loader.getResourceAsStream("/res/sound/" + file);
WaveData wavFile = WaveData.create(new BufferedInputStream(filePath)); //Retrieve wav file
AL10.alBufferData(data, wavFile.format, wavFile.data, wavFile.samplerate); //Store wav file data and properties in buffer object
wavFile.dispose(); //Discard wav file from stored memory
return data; //Return buffer ID
}
I cannot understand why this does not work when run from the jar, since when I look inside the jar file I can see that the res folder is indeed inside of it. What's stranger still is that I'm using more or less identical code to retrieve a text file in another part of the program and have been able to confirm that this is working correctly when run inside the IDE and from the jar. That code is as follows:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream mapPath = loader.getResourceAsStream("dat/maps/" + mapName);
I know similar questions have been asked here many times before, but I have not had any success with the solutions I found to those questions. I am pretty sure it's something to do with the files not being packaged correctly, but I cannot say how it should be done.
Here is the complete stack trace:
C:\Users\Jack>java -jar C:\Users\Jack\IdeaProjects\ProjectBlackSpace\out\artifacts\ProjectBlackSpace_jar\ProjectBlackSpace.jar
OpenALC10: true
OpenALC11: true
caps.ALC_EXT_EFX = true
Num HRTF specifiers = 2: true
Sample rate: default-44100
HRTF enabled: true
HRTF state: 0x3
OpenGL version: 4.5.0 NVIDIA 368.81
[LWJGL] Failed to load a library. Possible solutions:
a) Set -Djava.library.path or -Dorg.lwjgl.librarypath to the directory that contains the shared libraries.
b) Add the JAR(s) containing the shared libraries to the classpath.
[LWJGL] Enable debug mode with -Dorg.lwjgl.util.Debug=true for better diagnostics.
Unable to create from inputstream, Stream closed
Exception in thread "main" java.lang.NullPointerException
at projectBlackSpaceApp.Sounds.loadSound(Sounds.java:22)
at projectBlackSpaceApp.Player.init(Player.java:94)
at projectBlackSpaceApp.Game.init(Game.java:72)
at projectBlackSpaceApp.Main.run(Main.java:159)
at projectBlackSpaceApp.Main.init(Main.java:82)
at projectBlackSpaceApp.Main.main(Main.java:195)
AL lib: (EE) alc_cleanup: 1 device not closed
When running the program with -Dorg.lwjgl.util.Debug=true The results when running from the command line are no different, but when run from within the IDE it provides some more information:
[LWJGL] Version: 3.0.0 build 90
[LWJGL] OS: Windows 10 v10.0
[LWJGL] JRE: 1.8.0_60 amd64
[LWJGL] JVM: Java HotSpot(TM) 64-Bit Server VM v25.60-b23 by Oracle Corporation
[LWJGL] Loading library (system): lwjgl
[LWJGL] Loaded from java.library.path: libs\lwjgl.dll
[LWJGL] MemoryUtil accessor: MemoryAccessorUnsafe
[LWJGL] Loading library: OpenAL
[LWJGL] ThreadLocalUtil state: UnsafeState
[LWJGL] Loaded from java.library.path: libs\OpenAL.dll
OpenALC10: true
OpenALC11: true
caps.ALC_EXT_EFX = true
Num HRTF specifiers = 2: true
Sample rate: default-44100
HRTF enabled: true
HRTF state: 0x3
[LWJGL] Loading library: glfw
[LWJGL] Loaded from java.library.path: libs\glfw.dll
[LWJGL] Loading library: opengl32
[LWJGL] opengl32.dll not found in java.library.path=libs/
[LWJGL] Loaded from system paths
OpenGL version: 4.5.0 NVIDIA 368.81
[LWJGL] Loading library: jemalloc
[LWJGL] jemalloc.dll not found in java.library.path=libs/
[LWJGL] jemalloc.dll not found in system paths
[LWJGL] Using SharedLibraryLoader...
java.lang.RuntimeException: Failed to extract jemalloc library
at org.lwjgl.system.SharedLibraryLoader.load(SharedLibraryLoader.java:65)
at org.lwjgl.system.Library.loadNative(Library.java:139)
at org.lwjgl.system.jemalloc.JEmalloc.<clinit>(JEmalloc.java:37)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.lwjgl.system.MemoryManage.getInstance(MemoryManage.java:36)
at org.lwjgl.system.MemoryUtil$LazyInit.<clinit>(MemoryUtil.java:76)
at org.lwjgl.system.MemoryUtil.nmemAlloc(MemoryUtil.java:162)
at org.lwjgl.system.MemoryUtil.memAlloc(MemoryUtil.java:180)
at org.lwjgl.system.MemoryUtil.memUTF8(MemoryUtil.java:1530)
at org.lwjgl.system.APIUtil.apiArrayi(APIUtil.java:430)
at org.lwjgl.opengl.GL20.glShaderSource(GL20.java:425)
at projectBlackSpaceApp.Shaders.init(Shaders.java:29)
at projectBlackSpaceApp.Main.run(Main.java:123)
at projectBlackSpaceApp.Main.init(Main.java:82)
at projectBlackSpaceApp.Main.main(Main.java:195)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.RuntimeException: Failed to locate resource: jemalloc.dll
at org.lwjgl.system.SharedLibraryLoader.extractFile(SharedLibraryLoader.java:80)
at org.lwjgl.system.SharedLibraryLoader.load(SharedLibraryLoader.java:63)
... 20 more
[LWJGL] Failed to load a library. Possible solutions:
a) Set -Djava.library.path or -Dorg.lwjgl.librarypath to the directory that contains the shared libraries.
b) Add the JAR(s) containing the shared libraries to the classpath.
java.lang.UnsatisfiedLinkError: Failed to locate library: jemalloc.dll
at org.lwjgl.system.Library.loadNativeRelative(Library.java:177)
at org.lwjgl.system.Library.loadNative(Library.java:134)
at org.lwjgl.system.jemalloc.JEmalloc.<clinit>(JEmalloc.java:37)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.lwjgl.system.MemoryManage.getInstance(MemoryManage.java:36)
at org.lwjgl.system.MemoryUtil$LazyInit.<clinit>(MemoryUtil.java:76)
at org.lwjgl.system.MemoryUtil.nmemAlloc(MemoryUtil.java:162)
at org.lwjgl.system.MemoryUtil.memAlloc(MemoryUtil.java:180)
at org.lwjgl.system.MemoryUtil.memUTF8(MemoryUtil.java:1530)
at org.lwjgl.system.APIUtil.apiArrayi(APIUtil.java:430)
at org.lwjgl.opengl.GL20.glShaderSource(GL20.java:425)
at projectBlackSpaceApp.Shaders.init(Shaders.java:29)
at projectBlackSpaceApp.Main.run(Main.java:123)
at projectBlackSpaceApp.Main.init(Main.java:82)
at projectBlackSpaceApp.Main.main(Main.java:195)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
[LWJGL] [MemoryAllocator] Failed to load the jemalloc library.
[LWJGL] MemoryUtil allocator: StdlibAllocator
Adding the jemalloc.dll to the library directory does stop the runtime exception from happening, but it doesn't seem to have any other effect for better or worse.
Any help would be greatly appreciated.

check the difference between: "/res/sound/" and "dat/maps/". That is the /
UPDATE
From the stacktrace it looks like a shared library is expected to be present. Please do what is suggested:
Possible solutions:
a) Set -Djava.library.path or -Dorg.lwjgl.librarypath to the directory that contains the shared libraries.
b) Add the JAR(s) containing the shared libraries to the classpath.

Turns out the problem was twofold. Firstly I had not included an essential .dll file in my libs directory, secondly I was ending the file name with the extension ".wav" when I should have been using ".WAV". (facepalm)

Related

JNA undefined symbol on Ubuntu 20.04

I am attempting to load a native library using JNA, using this line:
MPV INSTANCE = Native.load("mpv", MPV.class, Map.of(Library.OPTION_STRING_ENCODING, "UTF-8"));
This works absolutely fine on an Ubuntu 20.04 that I installed in a Hyper-V VM on my main machine, but for some reason fails on an Ubuntu 20.04 native install.
The logs where it fails look like this:
Looking in classpath from {0} for {1}
Found library resource at {0}
Extracting library to {0}
Trying {0}
Found jnidispatch at {0}
Looking for library 'mpv'
Adding paths from jna.library.path: null
Trying libmpv.so
Loading failed with message: libmpv.so: cannot open shared object file: No such file or directory
Adding system paths: [/usr/lib/x86_64-linux-gnu, /lib/x86_64-linux-gnu, /usr/lib64, /lib64, /usr/lib, /lib, /lib/i386-linux-gnu, /usr/lib/x86_64-linux-gnu/libfakeroot]
Trying libmpv.so
Loading failed with message: libmpv.so: cannot open shared object file: No such file or directory
Looking for version variants
Trying /usr/lib/x86_64-linux-gnu/libmpv.so.1.107.0
Loading failed with message: /lib/x86_64-linux-gnu/libavfilter.so.7: undefined symbol: av_sscanf, version LIBAVUTIL_56
Looking in classpath from {0} for {1}
Loading failed with message: Native library (linux-x86-64/libmpv.so) not found in resource path ([file:/home/xxx/yyy/mpv.jar])
Exception in thread "JavaFX Application Thread"
java.lang.UnsatisfiedLinkError: Unable to load library 'mpv':
libmpv.so: cannot open shared object file: No such file or directory
libmpv.so: cannot open shared object file: No such file or directory
/lib/x86_64-linux-gnu/libavfilter.so.7: undefined symbol: av_sscanf, version LIBAVUTIL_56
Native library (linux-x86-64/libmpv.so) not found in resource path ([file:/home/xxx/yyy/mpv.jar])
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:302)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:455)
at com.sun.jna.Library$Handler.<init>(Library.java:192)
at com.sun.jna.Native.load(Native.java:596)
at hs.mediasystem.ext.mpv.MPV.<clinit>(MPV.java:12)
at hs.mediasystem.ext.mpv.MPVPlayer.<init>(MPVPlayer.java:47)
(... snipped 50 lines ...)
at com.sun.glass.ui.View.handleKeyEvent(View.java:547)
at com.sun.glass.ui.View.notifyKey(View.java:971)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
at java.base/java.lang.Thread.run(Thread.java:834)
Suppressed: java.lang.UnsatisfiedLinkError: libmpv.so: cannot open shared object file: No such file or directory
at com.sun.jna.Native.open(Native Method)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:191)
... 70 more
Suppressed: java.lang.UnsatisfiedLinkError: libmpv.so: cannot open shared object file: No such file or directory
at com.sun.jna.Native.open(Native Method)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:204)
... 70 more
Suppressed: java.lang.UnsatisfiedLinkError: /lib/x86_64-linux-gnu/libavfilter.so.7: undefined symbol: av_sscanf, version LIBAVUTIL_56
at com.sun.jna.Native.open(Native Method)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:235)
... 70 more
Suppressed: java.io.IOException: Native library (linux-x86-64/libmpv.so) not found in resource path ([file:/home/john/Downloads/MediaSystem/ui-plugins/mpv-plugin/mpv.jar])
at com.sun.jna.Native.extractFromResourcePath(Native.java:1095)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:276)
... 70 more
For some reason it cannot find some symbol av_sscanf in a dependent library. The wierd thing however is that this exact same code works in the Ubuntu installed in the VM.
Its output is:
Looking in classpath from {0} for {1}
Found library resource at {0}
Extracting library to {0}
Trying {0}
Found jnidispatch at {0}
Looking for library 'mpv'
Adding paths from jna.library.path: null
Trying libmpv.so
Loading failed with message: libmpv.so: cannot open shared object file: No such file or directory
Adding system paths: [/usr/lib/x86_64-linux-gnu, /lib/x86_64-linux-gnu, /usr/lib64, /lib64, /usr/lib, /lib]
Trying libmpv.so
Loading failed with message: libmpv.so: cannot open shared object file: No such file or directory
Looking for version variants
Trying /usr/lib/x86_64-linux-gnu/libmpv.so.1.107.0
Found library 'mpv' at /usr/lib/x86_64-linux-gnu/libmpv.so.1.107.0
I checked the versions and sizes of the libraries involved, and they seem to be all exactly the same:
john#Artec:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04 LTS
Release: 20.04
Codename: focal
john#Artec:~$ apt-cache policy libmpv1
libmpv1:
Installed: 0.32.0-1ubuntu1
Candidate: 0.32.0-1ubuntu1
Version table:
*** 0.32.0-1ubuntu1 500
500 http://nl.archive.ubuntu.com/ubuntu focal/universe amd64 Packages
100 /var/lib/dpkg/status
john#Artec:~$ apt-cache policy libavfilter7
libavfilter7:
Installed: 7:4.2.2-1ubuntu1
Candidate: 7:4.2.2-1ubuntu1
Version table:
*** 7:4.2.2-1ubuntu1 500
500 http://nl.archive.ubuntu.com/ubuntu focal/universe amd64 Packages
100 /var/lib/dpkg/status
john#Artec:~$ ll /usr/lib/x86_64-linux-gnu/libmpv.so.1.107.0
-rw-r--r-- 1 root root 2153952 jan 31 19:11 /usr/lib/x86_64-linux-gnu/libmpv.so.1.107.0
john#Artec:~$ ll /usr/lib/x86_64-linux-gnu/libavfilter.so.7
-rw-r--r-- 1 root root 3647472 mrt 7 09:39 /usr/lib/x86_64-linux-gnu/libavfilter.so.7.57.100
Any tips on how to debug this further would be much appreciated.
More Info
This turns out to be a problem where two libraries are loaded, but requiring different versions of a shared dependent library (in this case the libavfilter library is used by both opencv/ffmpeg and libmpv, but they need a slightly different version...).

Failed to locate library: liblwjgl.dylib

I am trying to create a Minecraft mod using this tutorial, altering the version to work with 1.15.1.
I moved a few files around to get it to work, but then this happened:
---- Minecraft Crash Report ----
// Everything's going to plan. No, really, that was supposed to happen.
Time: 12/04/20 1:44 PM
Description: Initializing game
java.lang.UnsatisfiedLinkError: Failed to locate library: liblwjgl.dylib
at org.lwjgl.system.Library.loadSystem(Library.java:147)
at org.lwjgl.system.Library.loadSystem(Library.java:67)
at org.lwjgl.system.Library.<clinit>(Library.java:50)
at org.lwjgl.system.MemoryUtil.<clinit>(MemoryUtil.java:97)
at org.lwjgl.system.Pointer$Default.<clinit>(Pointer.java:61)
at net.minecraft.client.MainWindow.func_211162_a(MainWindow.java:121)
at com.mojang.blaze3d.platform.GLX._initGlfw(GLX.java:69)
at com.mojang.blaze3d.systems.RenderSystem.initBackendSystem(RenderSystem.java:530)
at net.minecraft.client.Minecraft.<init>(Minecraft.java:367)
at net.minecraft.client.main.Main.main(Main.java:138)
at inject.mcp.client.Start.main(Start.java:19)
A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------
-- Head --
Thread: Render thread
Stacktrace:
at org.lwjgl.system.Library.loadSystem(Library.java:147)
at org.lwjgl.system.Library.loadSystem(Library.java:67)
at org.lwjgl.system.Library.<clinit>(Library.java:50)
at org.lwjgl.system.MemoryUtil.<clinit>(MemoryUtil.java:97)
at org.lwjgl.system.Pointer$Default.<clinit>(Pointer.java:61)
at net.minecraft.client.MainWindow.func_211162_a(MainWindow.java:121)
at com.mojang.blaze3d.platform.GLX._initGlfw(GLX.java:69)
at com.mojang.blaze3d.systems.RenderSystem.initBackendSystem(RenderSystem.java:530)
at net.minecraft.client.Minecraft.<init>(Minecraft.java:367)
-- Initialization --
Details:
Stacktrace:
at net.minecraft.client.main.Main.main(Main.java:138)
at inject.mcp.client.Start.main(Start.java:19)
-- System Details --
Details:
Minecraft Version: 1.15.1
Minecraft Version ID: 1.15.1
Operating System: Mac OS X (x86_64) version 10.15.2
Java Version: 1.8.0_241, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 547425376 bytes (522 MB) / 862978048 bytes (823 MB) up to 1908932608 bytes (1820 MB)
CPUs: 8
JVM Flags: 0 total;
Launched Version: mcp
Backend library: LWJGL version 3.2.1 build 12
Backend API: ~~ERROR~~ NoClassDefFoundError: Could not initialize class org.lwjgl.system.Library
GL Caps:
Using VBOs: Yes
Is Modded: Very likely; Jar signature invalidated
Type: Client (map_client.txt)
CPU: <unknown>
It seems that it cannot locate the library "liblwjgl.dylib".
Upon checking for this library, I found a file that might match:
liblwjgl.dylib.sha1 is located within the Project and external dependencies under lwjgl-3.2.1.jar
For some reason, however, that doesn't seem to work. I've not seen a file suffixed .sha1 before, what is it's a function? It contains one line, a hash (I am assuming sha1).
I am using macOS Catalina, Java 8 and Gradle 4.8.1 with Eclipse 4.15.0.
As I understand its a dylib file (dynamic library) that is somewhere in the game files or forge files, and files that are missing in game files can be easily fixed by reinstalling the game. And if that doesn't fix it try reinstalling the mod loader.

Can't find the dependent library for mavenized JCUDA in Eclipse

I am trying to setup mavenized JCUDA for a project that I am working on and am running into issues with telling java where to locate the library files.
Setting up and getting maven to build the .jar and .dll files has worked fine, I can see the correctly named .dll files in project\target\lib and I am setting my native library location to this folder.
The error I get when trying to run one of the programs from JCUDA JCublasSample.java (www.jcuda.org/samples/JCublasSample.java) is:
Creating input data... Performing Sgemm with Java... Performing Sgemm
with JCublas...
Exception in thread "main" java.lang.UnsatisfiedLinkError: Could not
load the native library.
Error while loading native library "JCublas-windows-x86_64" with base
name "JCublas" Operating system name: Windows 7 Architecture :
amd64 Architecture bit size: 64
Stack trace from the attempt to load the library as a resource:
java.lang.NullPointerException: No resource found with name
'/lib/JCublas-windows-x86_64.dll'
at jcuda.LibUtils.loadLibraryResource(LibUtils.java:149) at
jcuda.LibUtils.loadLibrary(LibUtils.java:83) at
jcuda.jcublas.JCublas.initialize(JCublas.java:93) at
jcuda.jcublas.JCublas.(JCublas.java:81) at
JCublasSample.sgemmJCublas(JCublasSample.java:64) at
JCublasSample.testSgemm(JCublasSample.java:49) at
JCublasSample.main(JCublasSample.java:25)
Stack trace from the attempt to load the library as a file:
java.lang.UnsatisfiedLinkError:
C:\Users\kristoffer.bernhem\git\SMlocalizer\target\lib\JCublas-windows-x86_64.dll:
Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method) at
java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941) at
java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857) at
java.lang.Runtime.loadLibrary0(Runtime.java:870) at
java.lang.System.loadLibrary(System.java:1122) at
jcuda.LibUtils.loadLibrary(LibUtils.java:94) at
jcuda.jcublas.JCublas.initialize(JCublas.java:93) at
jcuda.jcublas.JCublas.(JCublas.java:81) at
JCublasSample.sgemmJCublas(JCublasSample.java:64) at
JCublasSample.testSgemm(JCublasSample.java:49) at
JCublasSample.main(JCublasSample.java:25) at
jcuda.LibUtils.loadLibrary(LibUtils.java:128) at
jcuda.jcublas.JCublas.initialize(JCublas.java:93) at
jcuda.jcublas.JCublas.(JCublas.java:81) at
JCublasSample.sgemmJCublas(JCublasSample.java:64) at
JCublasSample.testSgemm(JCublasSample.java:49) at
JCublasSample.main(JCublasSample.java:25)
As explained by Guenther, the problem lies in supporting .dll files that are lacking. How would I go about sorting this error out?
This is being run in windows 7 (64bit) and run with JDK1.8.0_91.

JPL/SWI Prolog not working

I'm trying to use the SWI-Prolog JPL library, but I'm having problems.
I'm trying to let my Eclipse project access JPL, but when I try to start the program, I get the following error:
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: no jpl in java.library.path
I copied the jpl.jar into my project directory, and I set it on the build path. Additionally, I pass the following VM arguments:
-Djava.library.path="C:\Program Files\Prolog\bin"
(That's the directory where Prolog was installed).
What am I doing wrong?
EDIT: I don't seem to have the libpl.dll anywhere on my computer. Could this be causing my problem?
The jvm.dll of your running JDK/JRE must be available in your system PATH so that jpl.dll from java.library.path loads properly.
You have to take care to 32 bits / 64 bits consistency between your JPL installation and your running JVM - so do not try any mix.
Here is information from an old installation doc.
For such installation support, you should use the JPL mailing list.
You should set the java.library.path to the folder where the jpl.dll file is located. As far as I know it is the Prolog\bin folder.
A system-wide solution in a Mac environment (SWI-Prolog version 7.1.4 for x86_64-darwin13.1.0) would be to create the following symlink:
ln -s /usr/local/Cellar/swi-prolog/7.1.4/libexec/lib/swipl-7.1.4/lib/x86_64-darwin13.1.0/libjpl.jnilib /Library/Java/Extensions/libjpl.jnilib
Could be rather
ln -s
/Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin/libjpl.dylib
/Library/Java/Extensions/libjpl.dylib
? (no .inilib was found under darwin folder)
In my case still error on mojave (SWI-Prolog (threaded, 64 bits, version 8.0.2)):
Jan 03, 2020 12:10:55 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [ACTIONS] in context with path [/SVIZ] threw exception [Servlet execution threw an exception] with root cause
java.lang.UnsatisfiedLinkError: /Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin/libjpl.dylib: dlopen(/Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin/libjpl.dylib, 1): Library not loaded: #rpath/libswipl.8.dylib
Referenced from: /Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin/libjpl.dylib
Reason: image not found

How to use a JNI native library from Grails application

I'm developing a Grails web application and I need to use a JNI native library to access some specific hardware. For a simple Java application (see below) it works fine. To do this I just have to add the JAR to the Java build path and specify the "Native library location" (I use SpringSource Tool Suite on Windows7).
Working example:
import conceptacid.nativedriver.Driver;
public class Main {
public static void main(String[] args) {
System.out.println("starting...");
System.loadLibrary("AudioCardDriver");
Driver driver = Driver.instance();
String driverDescription = driver.getDriverDescription();
System.out.println( "Native application driver: " + driverDescription);
}
}
However, when I try to add it into my Grails application it fails:
Bootstrap.groovy:
import conceptacid.nativedriver.Driver;
class BootStrap {
def init = { servletContext ->
System.loadLibrary("AudioCardDriver");
Driver driver = Driver.instance();
String driverDescription = driver.getDriverDescription();
System.out.println( "Native application driver: " + driverDescription);
}
def destroy = {
}
}
the first line System.loadLibrary("AudioCardDriver"); is executed silently without any exception but the next line where I try to use my native code Driver driver = Driver.instance(); fails:
Running script C:\grails\scripts\RunApp.groovy
Environment set to development
[groovyc] Compiling 1 source file to D:\Projects3\mbr\target\classes
[delete] Deleting directory C:\Users\VShmyrev\.grails\1.3.7\projects\mbr\tomcat
Running Grails application..
2012-02-24 15:19:49,690 [main] ERROR context.GrailsContextLoader - Error executing bootstraps: java.lang.UnsatisfiedLinkError: conceptacid.nativedriver.AudioCardDriverJNI.swig_module_init()V
org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.UnsatisfiedLinkError: conceptacid.nativedriver.AudioCardDriverJNI.swig_module_init()V
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:251)
...
Caused by: java.lang.UnsatisfiedLinkError: conceptacid.nativedriver.AudioCardDriverJNI.swig_module_init()V
at conceptacid.nativedriver.AudioCardDriverJNI.swig_module_init(Native Method)
at conceptacid.nativedriver.AudioCardDriverJNI.<clinit>(AudioCardDriverJNI.java:70)
at conceptacid.nativedriver.Driver.instance(Driver.java:35)
at conceptacid.nativedriver.Driver$instance.call(Unknown Source)
at BootStrap$_closure1.doCall(BootStrap.groovy:7)
... 26 more
Application context shutting down...
I'm sure I put the DLL into a directory which is in my system PATH but it doesn't help.
What is the right way to use a native library in Grails application both in a development environment and in production?
Your DLL needs to be on a path specified in the Java system property java.library.path. On Windows the PATH environment variable and Linux the LD_LIBRARY_PATH environment variable are added to this system property. You can try logging the java.library.path system property to see if Java is looking in the right place for your DLL.
I'm guessing that the native library is being loaded multiple times in different classloaders, so forking a new JVM when running the app might help.

Categories