創建可執行命令行已經用Clojure寫的一個程序,我想執行它的命令行不在命令行專門調用java(如java -jar
)。我想要一個可執行文件,如myprogram
,它接受任何參數並運行我的程序。這裏有幾件事情,可能使這更容易:如何用Clojure
- 這是確定的假設安裝Java和
java
是路徑。 - 雖然在Windows上運行的解決方案將是一個很大的加分,你可以認爲這是所有被類UNIX操作系統上完成,如Mac OS X或Ubuntu Linux系統。
- 可以在某種腳本中調用Java。
- 可以使用其他語言,例如用戶可能已經安裝或未安裝的其他語言,例如Ruby,Python或Perl。所有bash將會很酷,因爲我可以假設人們有這個。
- 這是確定的,如果我有使用某種工具來建立一個二進制文件將執行,但我不想找一個期望與GUI界面來操作的.app或.exe文件(因此,例如,Oracle的appbundler不是我在這裏尋找的)。
我已經用一種方法在這條路上走得很遠,但我不得不懷疑是否有更好的方法。
僅供參考:我已經
試過了,我會在下面說明我的做法,但任何答案並不需要採用這種做法的。
我所做的就是創建一個名爲makescript
產生的uberjar一個雷音插件的base64編碼它,並在所謂的定界符變量的地方是一個Ruby腳本中,這樣的:
# ...ruby script...
BASE64_JAR = <<-JAR_BOUNDARY
# [...base64 encoded file here...]
JAR_BOUNDARY
你應該能夠運行ruby腳本。它將採用BASE64_JAR變量,取消編碼,將其放置在臨時文件中,然後通過調用java -jar <filename>
來執行它。
我用這種方法遇到的問題是Ruby的base64
圖書館和Clojure的clojure.data.codec.base64
庫似乎產生不同的字符串來表示的罐子,如果我使用Ruby由Clojure的編碼字符串不解碼原始文件。這可能與兩種語言之間字符串本身的編碼(UTF-8相關?也許)有關。下面是說明斷開REPL/IRB會議:
repl=> (def jar-contents (slurp "../target/myproj-0.1.0-SNAPSHOT-002-standalone.jar"))
repl=> (count jar-contents) ;; => 9433328
repl=> (def a-str (String. (clojure.data.codec.base64/encode (.getBytes jar-contents)) "UTF-8"))
repl=> (count a-str) ;; => 23265576
irb> f = File.open("target/pwgen-0.1.0-SNAPSHOT-002-standalone.jar", "r").read()
irb> p f.length # => 9657639
irb> b = Base64.encode64(f)
irb> p b.length # => 13564973
注意原始大小接近,但不盡相同,但編碼的版本是非常不同的。
雖然這是令人費解的,我想知道爲什麼會發生這種情況,我想我可以通過使腳本生成uberjar並將路徑傳遞給另一個Ruby腳本,然後將base64編碼(以及稍後解碼,也使用Ruby)獨立的JAR。問題依然存在:有沒有更好,更簡單的方法?我是否錯過了一些明顯的東西,或者這看起來真的很難?
這很好用!非常聰明的答案。 –