2013-11-01 28 views
5

創建可執行命令行已經用Clojure寫的一個程序,我想執行它的命令行在命令行專門調用java(如java -jar)。我想要一個可執行文件,如myprogram,它接受任何參數並運行我的程序。這裏有幾件事情,可能使這更容易:如何用Clojure

  1. 這是確定的假設安裝Java和java是路徑。
  2. 雖然在Windows上運行的解決方案將是一個很大的加分,你可以認爲這是所有被類UNIX操作系統上完成,如Mac OS X或Ubuntu Linux系統。
  3. 可以在某種腳本中調用Java。
  4. 可以使用其他語言,例如用戶可能已經安裝或未安裝的其他語言,例如Ruby,Python或Perl。所有bash將會很酷,因爲我可以假設人們有這個。
  5. 這是確定的,如果我有使用某種工具來建立一個二進制文件將執行,但我不想找一個期望與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。問題依然存在:有沒有更好,更簡單的方法?我是否錯過了一些明顯的東西,或者這看起來真的很難?

回答

2

這聽起來像你只是試圖使用更簡潔的語法從腳本引導你的應用程序。這可能像這樣最容易做到:

創建一個名爲myprogram一個新的bash腳本:

#!/usr/bin/bash 
# pass whatever command line args you have down through the script 
java -jar myjar.jar 

給它執行權限

chmod +x myprogram 

來看,它

./myprogram (with whatever params) 

如果您想要擺脫./您需要移動東西這樣腳本就會被你的PATH拾起。

請記住,你是沒有創建平臺特定的二進制可執行文件。這樣做幾乎會打敗首先使用jvm的目的。你只需要通過額外的間接層來調用它。

+0

的問題,這是需要我有一個單獨的jar文件。我想這是可能的,但有點不愉快。至於特定於平臺的二進制文件,我認爲大多數使用JVM的大型應用程序都是這樣做的 - 比如想到Eclipse或jEdit。但最後,我想要的只是自包含的命令行腳本。 –

+0

@door_number_three你說得對 - 用這種方法,你需要能夠引用主機系統上的jar。也許你可以編寫一個安裝腳本,將jar放在你需要的地方,然後鏈接到腳本中的腳本。 – yamafontes