用于 Java 的 Binfmt misc

出自 ArchWiki

出自 Wikipedia

binfmt_misc 是 Linux 内核的一项功能,允许识别任意可执行文件格式,并将其传递给特定的用户空间应用程序,例如模拟器和虚拟机。

通俗地说,这允许你使用 Java jar 或 Mono exe 等文件,通常你需要通过如下命令运行:

$ java -jar /path/to/MyProgram.jar
$ mono /path/to/MyProgram.exe

现在你可以直接使用以下命令运行:

$ MyProgram.jar
$ MyProgram.exe

只要可执行文件在 $PATH 中。

本文中的信息几乎完全取自 Linux 内核源代码树的 Documentation 子目录中的 binfmt_misc.txtjava.txt 文件。

设置

挂载 binfmt_misc

对于临时挂载

# mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc

要通过 fstab 进行持久挂载,请添加以下行

none  /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0

使用 binfmt_misc 注册文件类型

Arch 上的文件类型注册由 systemd-binfmt.service 处理(由 systemd 提供)。

Binfmt 注册行可以放在 /etc/binfmt.d 目录下的文件中。

行的内容在内核源代码树的 Documentation/admin-guide/binfmt-misc.rst 文件中进行了解释。

以下行将创建注册文件,用于运行 Java 二进制文件,而无需显式调用 java 命令(你仍然需要安装它)。前两行通过将 Java class 和 jar 文件重定向到下一节中描述的一组“封装”脚本来工作。最后一个条目以通常的方式运行 Java applet。

# binfmt_misc support for Java applications:
echo ':Java:M::\xca\xfe\xba\xbe::/usr/local/bin/javawrapper:' > /etc/binfmt.d/Java.conf
# binfmt_misc support for executable Jar files:
echo ':ExecutableJAR:E::jar::/usr/local/bin/jarwrapper:' > /etc/binfmt.d/ExecutableJAR.conf
# binfmt_misc support for Java Applets:
echo ':Applet:E::html::/opt/java/bin/appletviewer:' > /etc/binfmt.d/Applet.conf

重启 systemd-binfmt.service 以注册新的处理程序。注册的 binfmt 处理程序显示为 /proc/sys/fs/binfmt_misc 中的文件。查看此文件应显示注册的封装脚本的名称以及用于识别该文件类型的魔术字节或文件扩展名。

封装脚本

请参阅 /Wrapper 示例 以获取 jarwrapper 和 javawrapper 脚本以及相关程序。

一个简单的方案

这种简单的方案在大多数情况下都适用,执行过程中未检测到错误。创建文件 /etc/binfmt.d/java.conf

:Java:E::class::/usr/local/bin/javawrapper:

创建文件 /usr/local/bin/javawrapper

#!/bin/sh
file=${1%%.class}
file=${file/.\//}
java $file

不要忘记使其可执行

重启 systemd-binfmt.service。现在你可以测试了!

测试

创建一个简单的 HelloWorld.java 程序,例如以下内容

class HelloWorld {
    public static void main(String args[]) {
        System.out.println("Hello World!");
    }
}

像往常一样编译它,并使 .class 文件可执行

然后你应该能够通过简单地输入以下命令来运行它

$ ./HelloWorld.class

注释

  • 关于 binfmt_misc 的一些资料将其称为模块,但 Arch 将其构建到标准内核中。
  • 这里给出的设置适用于 Sun JRE 和 openjdk6。
  • binfmt_misc 也可用于其他文件类型。例如,为了能够运行 DOS/Windows 文件而无需显式指定 wine 程序,请添加以下注册条目
# binfmt_misc support for DOS / Windows applications via Wine
echo ':DOSWin:M::MZ::/usr/bin/wine:' > /proc/sys/fs/binfmt_misc/register