jarファイルにライブラリが必要なGroovyスクリプトがあります。それをクラスパスに追加するにはどうすればよいですか?スクリプトを実行可能にしたいので、スクリプト#!/usr/bin/env groovy
の先頭で使用しています。
9 に答える
で groovy スクリプトを開始することに#!/usr/bin/env groovy
は、非常に重要な制限があります。追加の引数を追加することはできません。クラスパスを構成することはできず、定義またはデバッグで groovy を実行することはできません。これはグルーヴィーな問題ではありませんが、shebang( #!
) の動作の制限です。すべての追加の引数は単一の引数として扱われるため、 rathenコマンドを引数で実行するように#!/usr/bin/env groovy -d
指示しています。/usr/bin/env
groovy -d
groovy
d
この問題には回避策があり、groovy スクリプトで bash を使用して groovy をブートストラップする必要があります。
#!/bin/bash
//usr/bin/env groovy -cp extra.jar:spring.jar:etc.jar -d -Dlog4j.configuration=file:/etc/myapp/log4j.xml "$0" $@; exit $?
import org.springframework.class.from.jar
//other groovy code
println 'Hello'
すべての魔法は最初の 2 行で起こります。最初の行は、これがbash
スクリプトであることを示しています。bash
が実行を開始し、最初の行が表示されます。Inbash
#
はコメント用で、ルート ディレクトリに//
折りたたまれます。そのため、すべての必要な引数で groovy を開始/
するbash
実行します。/usr/bin/env groovy -cp extra.jar:spring.jar:etc.jar -d -Dlog4j.configuration=file:/etc/myapp/log4j.xml "$0" $@
は"$0"
スクリプトへのパスで、$@
は引数です。これで groovy が実行され、最初の 2 行が無視され、groovy スクリプトが表示され、終了して に戻りますbash
。bash
その後exit $?1
、groovy からのステータス コードで ( ) 終了します。
本当に必要な場合は、実行時に次のコマンドを使用してJARをロードすることもできます。
this.getClass().classLoader.rootLoader.addURL(new File("file.jar").toURL())
これを行う私のお気に入りの方法は、Groovy Grapes を使用することです。これらは Maven Central Repository にアクセスし、参照されている jar をダウンロードして、クラスパスに配置します。その後、他のライブラリと同じようにライブラリを使用できます。構文は非常に単純です。
@Grab(group='com.google.collections', module='google-collections', version='1.0')
詳細については、こちらをご覧ください。ここでの大きな利点の 1 つは、スクリプトを配布するときに依存関係を配布する必要がないことです。この方法の唯一の欠点は、Jar が Maven リポジトリにある必要があることです。
jar を $HOME/.groovy/lib に追加できます。
Groovy Grape を試すこともできます。注釈を使用してクラスパスを変更できます。現在は実験的ですが、かなりクールです。docs.groovy-lang.org/.../grapeを参照してください
Java の場合と同じです。
これは、MySQL ステータス監視スクリプトを実行する例です。mysql.jar には、スクリプト status.groovy から呼び出す MySQL コネクタが含まれています。
groovy -cp mysql.jar status.groovy ct1
以下は、Patrick のソリューション、Maarteen Boekhold のソリューション、および Linux と Cygwin の両方で機能する foozbar のコメントの組み合わせです。
#!/bin/bash
// 2>/dev/null; SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
// 2>/dev/null; OPTS="-cp $SCRIPT_DIR/lib/extra.jar:$SCRIPT_DIR/lib/spring.jar"
// 2>/dev/null; OPTS="$OPTS -d"
// 2>/dev/null; OPTS="$OPTS -Dlog4j.configuration=file:/etc/myapp/log4j.xml"
// 2>/dev/null; exec groovy $OPTS "$0" "$@"; exit $?
import org.springframework.class.from.jar
//other groovy code
println 'Hello'
使い方:
//
は有効な groovy コメントであるため、Groovy はすべての bash コマンドを無視します。//
はエラーを返しますが、エラー出力は にリダイレクトされる/dev/null
ため、表示されません。- bash は、前のコマンドが失敗した場合でも、セミコロンに続くコマンドを実行します。
exec
新しいプロセスをフォークせずに、現在のプロセスの現在のプログラムを置き換えます。したがって、groovy は元のスクリプト プロセス内で実行されます (ps
このプロセスは、groovy 実行可能ファイルではなくスクリプトとして表示されます)。- 次の
exit $?
ステートメントexec groovy
は、bash が残りのスクリプトを bash スクリプトとして解釈しようとするのを防ぎ、groovy スクリプトからの戻りコードも保持します。
上記の bash トリックは、スクリプト内で通常の import ステートメントを使用できるため、場合によっては RootLoader トリックよりも便利です。RootLoader トリックを使用すると、リフレクションを使用してすべてのクラスをロードする必要があります。これは状況によっては問題ありませんが (JDBC ドライバーをロードする必要がある場合など)、不便な場合もあります。
スクリプトが Cygwin で決して実行されないことがわかっている場合、Patrick または Maarteen のソリューションを使用すると、エラーの生成と破棄のオーバーヘッドが回避されるため、パフォーマンスがわずかに向上する可能性があります。