背景:
我正在用Java编写一个跨平台音频播放器。在Linux上,我以appimage的形式分发它(
https://appimage.org/
). 我使用VLC/VLCJ作为解码引擎。
appimages的基本原则是将所有必需的库与appimages一起包含,而这些库在默认情况下不能合理地预期会与发行版一起包含。这样做的目的是不需要用户解析依赖关系和/或处理库和程序之间的版本控制差异。他们还建议对
以前的
一些Linux发行版的版本,以确认一切正常。
默认情况下,Ubuntu 16.04和Fedora 27.16不安装libvlc。我相信这在其他发行版中很常见。因此,我想在appimage中打包libvlc库。
问题:
在Linux上,我无法让vlcj识别/查找
libvlc.so
和
libvlccore.so
除非是通过配电盘安装的。
设置:
-
我通过发行版安装了VLC,程序运行正常。
-
我抄了
libvlc.so公司
,
libvlccore.so公司
,以及其他关联库(从它们在我的分发中的默认位置到我的项目中的文件夹)。
-
我将该文件夹添加到本机库搜索路径(请参阅下面的代码)。
-
我卸载了VLC。
-
我试着运行我的程序。它崩溃了,错误粘贴在下面。
注意:我对Windows使用了同样的基本方法,而且在那里工作得很好。
简化代码:
String nativeVLCLibPath = Hypnos.getRootDirectory().resolve( "lib/nix/vlc/" ).toAbsolutePath().toString();
System.out.println ( "Trying to look for libraries in: " + nativeVLCLibPath );
NativeLibrary.addSearchPath( RuntimeUtil.getLibVlcLibraryName(), nativeVLCLibPath );
错误消息:
尝试在以下位置查找库:
/d/programming/workspace/MusicPlayer/stage/lib/nix/vlc SLF4J:失败
加载类“org.slf4j.impl.StaticLoggerBinder”。SLF4J:默认
to no operation(NOP)logger实现SLF4J:请参阅
http://www.slf4j.org/codes.html#StaticLoggerBinder
为了进一步
细节。2018年8月5日下午22:14:32 net.joshuad.hypnos.hypnos开始
严重:类java.lang.RuntimeException:在顶部捕获到异常
催眠水平。退出。java.lang.RuntimeException:未能加载
本地图书馆。
错误为“无法加载库'vlc':JNA本机支持
(linux-amd64/libvlc.so)在资源路径中找不到
/usr/lib/java/java/java-8-openjdk-amd64/jre/lib/resources.jar/usr/lib/java/java-8-openjdk-amd64/jre/lib/rt.jar/usr/lib/java/java/java/java-8-openjdk-amd64/jre/lib/jsse.jar/usr/lib/jsse.jar/usr/lib/java/jvm/java/java/java/java/java-lib/java-openjjjjjjr/lib/lib/java/java/java/java/lib/lib/lib/lib/resources.jar.jar/usr/usr/java/java/java/jjjjjava/openjfx/jre/lib/ext/jfxrt.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jar/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunjce/sunjce-provider.jar/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/localedata.jar/usr/lib/jvm/java/java-8-openjdk-amd64/jre/lib/lib/ext/jacess.jar/usr/lib/lib/java/jvm/java/java/lib/jjvm/jjvm/java-8/jvm/jvm/java-8/java-8-openjvm/java-8-openjjk-8 jdk-amd64/jre/lib/ext/icedtea sound.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunpkcs11.jar/usr/lib/lib/zipfs.jar/usr/lib/jpfs/java/jvm/java-8-openjdk-amd64/jre/jre/lib/lib/ext/cldrdata.jar/usr/lib/lib/lib/cldrdata.jar/usr/lib/jvm/java/jvm/java/java/java/java/java/openjd64/jre/jre/jre/lib/lib/lib/ext/nashorn.jar/usr/shar/share/java/java/java/java/java/java-atk包装器.jar/jar/jar/jar//d////stage/lib/commons-cli-1。4.jar:/d/programming/workspace/MusicPlayer/stage/lib/fuzzywuzzy-1.1.8.jar:/d/programming/workspace/MusicPlayer/stage/lib/jaudiotagger-2.2.6-SNAPSHOT.jar:/d/programming/workspace/MusicPlayer/stage/lib/jsoup-1.11.2.jar:/d/programming/workspace/MusicPlayer/stage/lib/commons-text-1.1.jar:/d/programming/workspace/MusicPlayer/stage/lib/commons-lang3-3.7.jar:/d/programming/workspace/MusicPlayer/stage/lib/jnativehook-2.0.2.jar:/d/programming/workspace/MusicPlayer/stage/lib/jlastfm.jar:/usr/lib/jvm/java-8-openjd64/lib/javafx mx.jar:/d/programming/workspace/MusicPlayer/stage/lib/jna-3.5.2.jar/stage/lib/platform-3.5.2.jar:/d/programming/workspace/MusicPlayer/stage/lib/slf4j-api-1.7.10.jar:/d/programming/workspace/MusicPlayer/stage/lib/vlcj-3.10.1.jar)”。
所需的本机库名为“libvlc.so”和
“libvlccore.so”。
在下面的文本中表示目录的名称
包含“libvlc.so”和“libvlccore.so”。。。
有许多不同的方法可以指定在何处查找
本机库:
一。在应用程序代码的开头包括NativeLibrary.addSearchPath(“vlc”,“”)。
2。在应用程序代码的开头包括System.setProperty(“jna.library.path”,“”)。
三。启动应用程序时在命令行中指定-Djna.library.path=。
四。添加到系统搜索路径(并重新启动)。
如果这仍然不起作用,那么可能需要显式地
将本机库目录添加到操作系统配置中
-例如,在Linux上,这可能意味着设置LD_LIBRARY_PATH环境变量,或将配置添加到“/etc/LD.so.conf”
文件或“/etc/ld.so.conf.d”目录。在这些选项中,设置
LD_LIBRARY_PATH是唯一不需要根目录的路径
特权。
最后,不可能混合CPU体系结构-不可能
64位Java虚拟机可以加载32位本机
图书馆。
日志中可能有更多信息。
在
uk.co.caprica.vlcj.binding.LibVlcFactory.create(LibVlcFactory.java:198)
在
uk.co.caprica.vlcj.player.MediaPlayerFactory(MediaPlayerFactory.java:259)
在
uk.co.caprica.vlcj.component.AudioMediaPlayerComponent.onGetMediaPlayerFactory(AudioMediaPlayerComponent.java:177)
在
uk.co.caprica.vlcj.component.AudioMediaPlayerComponent。(AudioMediaPlayerComponent.java:109)
在
net.joshuad.hypnos.audio.VLCAudioPlayer(VLCAudioPlayer.java:75)
在net.joshuad.hypnos.audio.AudioSystem上
在net.joshuad.hypnos.hypnos.start(hypnos.java:726)上
com.sun.javafx.application.launchempl.lambda$launchApplication1$8(launchempl.java:863)
在
com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
在
com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
在java.security.AccessController.doPrivileged(本机方法)上
com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
在
com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
在com.sun.glass.ui.gtk.GtkApplication.\u runLoop(本地方法)上
com.sun.glass.ui.gtk.GtkApplication.lambda$null$5(GtkApplication.java:139)
运行(Thread.java:748)
2018年8月5日22:14:32 pm NET.JouHua.ActhNOS.催眠退出信息:退出
请求:未知错误
申请开始方法异常2018年8月5日22:14:32 PM
NET.Jojua.HythNo.HypNOS退出信息:退出要求:正常
应用程序停止方法中的异常
java.lang.reflect.InvocationTargetException位于
sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)位于
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在java.lang.reflect.Method.invoke(Method.java:498)上
com.sun.javafx.application.launchempl.launchApplicationWithArgs(launchempl.java:389)
在
com.sun.javafx.application.launchempl.launchApplication(launchempl.java:328)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在java.lang.reflect.Method.invoke(Method.java:498)上
sun.launcher.launchelper$FXHelper.main(launchelper.java:767)
原因:java.lang.RuntimeException:应用程序启动中出现异常
方法
com.sun.javafx.application.launchempl.launchApplication1(launchempl.java:917)
在
com.sun.javafx.application.launchempl.lambda$launchApplication$1(launchempl.java:182)
在java.lang.Thread.run(Thread.java:748)上,由以下原因引起:
位于的java.lang.NullPointerException
Sujuad。催眠。催眠。退出(催眠。爪哇:692)AT
net.joshuad.hypnos.hypnos.start(hypnos.java:872)网址
com.sun.javafx.application.launchempl.lambda$launchApplication1$8(launchempl.java:863)
在
com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
在
com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
在java.security.AccessController.doPrivileged(本机方法)上
com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
在
com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
在com.sun.glass.ui.gtk.GtkApplication.\u runLoop(本地方法)上
com.sun.glass.ui.gtk.GtkApplication.lambda$null$5(GtkApplication.java:139)
... 1运行application net.joshuad.hypnos.hypnos时出现更多异常
搜索文件夹的内容(显示libvlc.so和其他文件夹):
joshua @Joshua-PC /d/programming/workspace/MusicPlayer/stage/lib/nix/vlc
$ ls -l
total 2.5M
-rwxr-xr-x 1 joshua joshua 1.1M May 15 00:26 libvlccore.so
-rwxr-xr-x 1 joshua joshua 1.1M May 15 00:26 libvlccore.so.9.0.0
lrwxrwxrwx 1 joshua joshua 21 Aug 2 22:57 libvlc_pulse.so -> libvlc_pulse.so.0.0.0
lrwxrwxrwx 1 joshua joshua 21 Aug 2 22:57 libvlc_pulse.so.0 -> libvlc_pulse.so.0.0.0
-rwxr-xr-x 1 joshua joshua 14K May 15 00:26 libvlc_pulse.so.0.0.0
-rwxr-xr-x 1 joshua joshua 150K May 15 00:26 libvlc.so
-rwxr-xr-x 1 joshua joshua 150K May 15 00:26 libvlc.so.5.6.0
lrwxrwxrwx 1 joshua joshua 21 Aug 2 22:57 libvlc_vdpau.so -> libvlc_vdpau.so.0.0.0
lrwxrwxrwx 1 joshua joshua 21 Aug 2 22:57 libvlc_vdpau.so.0 -> libvlc_vdpau.so.0.0.0
-rwxr-xr-x 1 joshua joshua 18K May 15 00:26 libvlc_vdpau.so.0.0.0
lrwxrwxrwx 1 joshua joshua 26 Aug 2 22:57 libvlc_xcb_events.so -> libvlc_xcb_events.so.0.0.0
lrwxrwxrwx 1 joshua joshua 26 Aug 2 22:57 libvlc_xcb_events.so.0 -> libvlc_xcb_events.so.0.0.0
-rwxr-xr-x 1 joshua joshua 9.9K May 15 00:26 libvlc_xcb_events.so.0.0.0
drwxr-xr-x 1 joshua joshua 4.0K Aug 2 22:57 lua
drwxr-xr-x 1 joshua joshua 4.0K Aug 2 22:57 plugins
-rwxr-xr-x 1 joshua joshua 11K May 15 00:26 vlc-cache-gen