我已经在Clojure中编写了一个程序,我想在命令行上执行它而不需要在命令行上专门调用java(例如java -jar
)。我想要一个可执行文件,例如myprogram
,它接受任何参数并运行我的程序。以下是一些可能使这更容易的事情:
java
在路径中。我已经用一种方法走了很远的路,但我不得不怀疑是否有更好的方法。
仅供参考:我已经尝试了
我将在下面描述我的方法,但任何答案都不需要遵循这种方法。
我所做的是创建一个名为makescript
的lein插件,它生成一个uberjar,base64对其进行编码,并将其放在一个所谓的heredoc变量的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
库似乎生成不同的字符串来表示jar,而Clojure编码的字符串不能解码为如果我使用Ruby,原始文件。这可能与两种语言之间的字符串本身(与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
请注意原始大小接近但不相同,但编码版本差异很大。
虽然这很令人费解但我想知道为什么会发生这种情况,我想我可以绕过这个问题,让makecript只生成uberjar并将路径传递给另一个Ruby脚本,然后将其编译为base64(后来解码) ,也使用Ruby)独立的JAR。问题仍然存在:是否有更好,更简单的方法?我错过了一些明显的东西,还是这看起来真的很难?
答案 0 :(得分:4)
如果你真的想这样做,你可以在bash可执行文件中uuencode jar文件(或任何其他二进制文件),请参阅以下示例:Embed a Executable Binary in a shell script
答案 1 :(得分: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的目的。你只是通过一个额外的间接层来调用它。
答案 2 :(得分:1)
如何将clojure作为解释性脚本运行。创建一个名为mytest
的新文件:
#!/usr/bin/clojure
(print "hello world")
然后
chmod +x mytest
然后运行它
./mytest
这有很多缺点。开始真的很慢。这个简单的1班轮耗时2秒钟以上!您只会得到一个文件。可能这仅对最简单的事情有用。但是,如果您只是想快速做一些非生产性的事情或测试某些东西,这可能会很有用。
答案 3 :(得分:1)