Clojure でプログラムを作成しましたが、コマンド ラインで特に Java を呼び出さずにコマンド ラインで実行したいと考えています ( などjava -jar
)。myprogram
任意の引数を受け入れてプログラムを実行する、 などの単一の実行可能ファイルが必要です。これを簡単にするいくつかのことを次に示します。
java
Java がインストールされていて、それがパスにあると想定しても問題ありません。- Windows で動作するソリューションは大きな利点ですが、これはすべて Mac OS X や Ubuntu などの UNIX ライクなオペレーティング システムで行われていると想定できます。
- ある種のスクリプトで Java を呼び出すことは問題ありません。
- Ruby、Python、Perl など、ユーザーがインストールしたかどうかに関係なく、他の言語を使用してもかまいません。私は人々がそれを持っていると仮定できるので、オールバッシュはクールでしょう。
- 何らかのツールを使用して実行するバイナリを作成する必要がある場合は問題ありませんが、GUI インターフェイスで動作することを期待する .app または .exe ファイルを探しているわけではありません (たとえば、Oracle の appbundler はここで探しています)。
私は1つのアプローチでこの道をかなり進んできましたが、もっと良い方法があるかどうか疑問に思う必要があります.
参考までに:私がすでに試したこと
以下で私のアプローチについて説明しますが、このアプローチに従う必要はまったくありません。
私が行ったことは、uberjarmakescript
を生成するという lein プラグインを作成し、それを 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
ライブラリが jar を表すために異なる文字列を生成しているように見え、Ruby を使用すると Clojure によってエンコードされた文字列が元のファイルにデコードされないことです。これは、2 つの言語間の文字列自体のエンコーディング (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
生のサイズは近いですが同じではありませんが、エンコードされたバージョンは大きく異なることに注意してください。
これは不可解であり、なぜこれが起こるのか知りたいのですが、makescript で uberjar を生成し、パスを別の Ruby スクリプトに渡すことで問題を回避できると思います。 Ruby) スタンドアロン JAR。質問はまだ残っています: より良い、より簡単な方法はありますか? 私は明らかな何かを見逃していますか、それともこれは本当に難しいですか?