Linux

在不呼叫 Java 的情況下啟動 Java 程序

  • August 2, 2016

能夠通過從終端呼叫類文件來啟動 Java 程序會很方便(並且在 GUI 中點兩下時讓它在終端上執行它,但這並不重要)。到目前為止,我只幫助自己進行以下臨時修復:

alias cs='java charstat.Charstat'

Linux 將文件辨識為 Java:

charstat/Charstat.class: compiled Java class data, version 52.0 (Java 1.8)

那麼有沒有辦法讓電話硬連線?這裡是 Ubuntu 16.04,但歡迎提供一般性答案。


問題結束,故障排除部分開始。


更新

迄今為止,最有希望的行動路線是 Gilles 提出的路線。所以我跑了:

echo ":java-class:M:0:cafebabe::/usr/bin/java:" | sudo tee /proc/sys/fs/binfmt_misc/register

現在,

tomasz@tomasz-Latitude-E4200:~/Desktop$ cat /proc/sys/fs/binfmt_misc/java-class
enabled
interpreter /usr/bin/java
flags: 
offset 0
magic 6361666562616265

但,

tomasz@tomasz-Latitude-E4200:~/Desktop$ ./Void.class 
bash: ./Void.class: cannot execute binary file: Exec format error

這是在 Ubuntu 14.04 上完成的。它有:

binfmt-support/trusty,now 2.1.4-1 amd64 [installed,automatic]
 Support for extra binary formats

如果這很重要,我認為它不會在 16.04 上自動安裝。

昨天,根據 Mark Plotnick 的評論,我與本指南搏鬥,但無濟於事。它在 處引入了一個包裝器/usr/local/bin/javawrapper,而 Gilles 的解決方案不包含該包裝器。不過那是針對 Arch Linux 的。

更新 2 (Ubuntu 16.06)

16.06:

tomasz@tomasz-Latitude-E4200:~/Desktop/io$ cat /proc/sys/fs/binfmt_misc/Java 
enabled
interpreter /usr/local/bin/javawrapper
flags: 
offset 0
magic cafebabe

和,

tomasz@tomasz-Latitude-E4200:~/Desktop/io$ ./Nain.class 
bash: ./Nain.class: No such file or directory

更新 3

之後echo ":java-class:M:0:\xca\xfe\xba\xbe::/usr/bin/java:" | sudo tee /proc/sys/fs/binfmt_misc/register

tomasz@tomasz-Latitude-E4200:~/Desktop/io$ java Main 
Please input the file location and name.
^Ctomasz@tomasz-Latitude-E4200:~/Desktop/io$ ./Main.class 
Error: Could not find or load main class ..Main.class

作為記錄:

tomasz@tomasz-Latitude-E4200:/proc/sys/fs/binfmt_misc$ cat java-class 
enabled
interpreter /usr/bin/java
flags: 
offset 0
magic cafebabe

Linux

Ubuntu 已經為 jar 做到了這一點。使用openjdk-8-jre 包(和早期版本),執行一個 jar 呼叫jexec它。這不適用於類,可能是因為類很少是獨立的執行檔而不是庫(同樣,jar 也是如此)。

您可以配置相同的底層機制來處理類。該機制是 Linux binfmt_misc功能,它允許核心通過幫助程序執行任意文件。

因為Java的命令行真的很奇怪,你需要通過一個包裝器將文件名轉換成java命令能夠執行的東西。將此腳本另存為/usr/local/bin/javarun並使其可執行:

#!/bin/sh
case "$1" in
 */*) dir="${1%/*}"; base="${1##*/}";;
 *) dir="."; base="$1";;
esac
shift
case "$base" in
 [!-]*.class) base="${base%.*}";;
 *) echo >&2 "Usage: $0 FILENAME.class [ARGS...]"; exit 127;;
esac
case "$CLASSPATH" in
 "") exec java -cp "$dir" "$base" "$@";;
 *) exec java -cp "$dir:$CLASSPATH" "$base" "$@";;
esac

以下命令應該是類的訣竅。有關解釋,請參閱https://unix.stackexchange.com/a/21651核心文件

echo ":java-class:M:0:\xca\xfe\xba\xbe::/usr/local/bin/javarun:" | sudo tee /proc/sys/fs/binfmt_misc/register

執行一次以啟用它。要刪除設置,請執行sudo rm /proc/sys/fs/binfmt_misc/java-class. 對設置滿意後,將以下命令添加到/etc/rc.local

echo >/proc/sys/fs/binfmt_misc/register ":java-class:M:0:\xca\xfe\xba\xbe::/usr/local/bin/javarun:"

Zsh

如果你使用zsh作為你的 shell,你可以通過定義一個後綴 alias使其基於文件的副檔名執行文件。

alias -s class=javarun

您需要與javarun上面相同的腳本。當然,這只適用於 zsh,不適用於 bash、文件管理器、腳本(執行此命令的 zsh 腳本除外),…

引用自:https://unix.stackexchange.com/questions/299483