Gau*_*ani 5 java native glibc jna musl
我有一个 Java 桌面应用程序,应该可以在 GNU Linux 发行版(Debian 和 Ubuntu)和 MUSL Linux 发行版(Alpine)中运行。我的应用程序也使用本机库,并且两种类型的 Linux 发行版的本机库构建都不同。
我会将两者与我的申请放在不同的文件夹中。因此,在运行时,Java 程序需要根据 Linux(GNU 或 MUSL)选择正确的本地库发行版。
我没有找到任何机制来了解 Java 程序中运行的是哪个 Linux 发行版 JVM。
我正在考虑从 Linux 的 /etc/ 文件夹中读取操作系统文件的一种方法。但我认为这不是一个好的解决方案(因为某些自定义构建可能会更改此细节),有人可以为这个问题建议一些更好的解决方案吗?或者如何做到这一点?
使用Java/JNA,您可以映射gnu_get_libc_version()函数并尝试在加载后执行它libc。如果它有效,那么您就使用了 glibc (GNU)。如果您发现UnsatisfiedLinkError该函数未找到,则说明您使用的是其他 libc。
映射函数:
public interface Libc extends Library {
Libc INSTANCE = Native.load("c", Libc.class);
String gnu_get_libc_version();
}
Run Code Online (Sandbox Code Playgroud)
叫它:
public class GnuOrMusl {
public static void main(String[] args) {
try {
System.out.println("On GNU libc version " + Libc.INSTANCE.gnu_get_libc_version());
} catch (UnsatisfiedLinkError e) {
System.out.println("Not on glibc!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您处于具有 glibc 兼容性的容器化环境中,此检测可能会指示 glibc,但这会引发一个问题:哪种版本的库适合该环境。
可能有类似的方法具有独特的功能来区分其他 libc 变体和 MUSL,但据我所知,MUSL 试图如此符合标准,以至于它实际上不允许识别自己。
查找 GNU 发行版的另一个选项是uname -o可以使用 ProcessBuilder 执行的命令。
在非 GNU (Alpine) 上它只是“Linux”,而在 Ubuntu、Debian 和 OpenSUSE 上它是“GNU/Linux”。
/lib*您还可以通过迭代目录查找 libc 变体来成功确定 GNU 与 MUSL 。这与编译 JDK 时所采用的方法类似,后者执行ldd命令并从输出中解析库。
例如,迭代/libAlpine linux 中的目录会给出以下链接:libc.musl-x86_64.so.1 -> ld-musl-x86_64.so.1
在 Debian 中/lib32有libc.so.6 -> libc-2.28.so,在 OpenSUSE 中/lib64我看到类似的东西:libc.so.6 -> libc-2.26.so,而 Ubuntu 中/lib/aarch64-linux-gnu有libc-2.27.so.
如果您停留在 Java 领域,确定/lib搜索路径可能需要一些尝试和错误。解析命令行的输出ldd `which ls`可能会得到一个包含gnuor的字符串musl。
至于确定使用哪个 Linux 发行版,从/etc文件夹中读取是一个很好的直觉。我管理基于 Java 的操作系统和硬件信息 (OSHI) 项目,并浏览了几乎所有选项来确定您正在运行哪个发行版。您可以在本课程中看到所有劳动成果。
我将引用该文件中的评论:
系列/版本信息有两个相互竞争的选项。较新的系统正在采用标准 /etc/os-release 文件: https://www.freedesktop.org/software/systemd/man/os-release.html
某些系统仍在使用 lsb 标准,该标准解析各种 /etc/*-release 文件,并且最容易通过命令行 lsb_release -a 访问,请参见此处: https: //linux.die.net/man/1/lsb_release在这种情况下,/etc/lsb-release 文件(如果存在)可以选择覆盖 /etc/distrib-release 文件中的信息,其中显示:“Distributor release xx(代号)”
代码的逻辑是:
/etc/system-release/etc/os-releaselsb_release命令/etc/lsb-release/etc/*-release文件。这些文件包含类似的密钥NAME,可以帮助您解决问题。
请随意复制和使用该文件或变体,或者仅使用该项目作为依赖项。
| 归档时间: |
|
| 查看次数: |
4087 次 |
| 最近记录: |