У меня есть groovy script, которому нужна библиотека в банке. Как добавить это в путь к классам? Я хочу, чтобы script был исполняемым, поэтому я использую #!/usr/bin/env groovy
в верхней части моего script.
Как включить банки в groovy script?
Ответ 1
Если вам действительно нужно, вы можете загрузить JAR во время выполнения с помощью:
this.getClass().classLoader.rootLoader.addURL(new File("file.jar").toURL())
Ответ 2
Запуск groovy script с #!/usr/bin/env groovy
имеет очень важное ограничение - Никакие дополнительные аргументы не могут быть добавлены. Нельзя настроить путь к классам, без запуска groovy с параметрами или отлаживать. Это не проблема groovy, но ограничение в том, как работает shebang (#!
) - все дополнительные аргументы рассматриваются как один аргумент, поэтому #!/usr/bin/env groovy -d
сообщает /usr/bin/env
выполнить команду groovy -d
rathen then groovy
с аргументом d
.
Обходной путь для этой проблемы связан с загрузкой groovy с bash в groovy script.
#!/bin/bash
//usr/bin/env groovy -cp extra.jar:spring.jar:etc.jar -d -Dlog4j.configuration=file:/etc/myapp/log4j.xml "$0" [email protected]; exit $?
import org.springframework.class.from.jar
//other groovy code
println 'Hello'
Вся магия происходит в первых двух строках. Первая строка говорит нам, что это bash
script. bash
начинает работать и видит первую строку. В bash
#
для комментариев и //
свернут до /
, который является корневым каталогом. Итак, bash
будет запускать /usr/bin/env groovy -cp extra.jar:spring.jar:etc.jar -d -Dlog4j.configuration=file:/etc/myapp/log4j.xml "$0" [email protected]
, который запускает groovy со всеми нашими нужными аргументами. "$0"
- это путь к нашему script, а [email protected]
- аргументы. Теперь выполняется groovy, и он игнорирует первые две строки и видит наш groovy script, а затем возвращается к bash
. bash
затем выйдет (exit $?1
) с кодом состояния из groovy.
Ответ 3
Вы можете добавить банки в $HOME/.groovy/lib
Ответ 4
Мой любимый способ сделать это с помощью Groovy Grapes. Они получают доступ к центральному репозиторию Maven, загружают упоминаемую банку и затем помещают ее в путь к классам. Затем вы можете использовать библиотеку, как и любую другую библиотеку. Синтаксис очень прост:
@Grab(group='com.google.collections', module='google-collections', version='1.0')
Здесь вы можете подробнее прочитать . Одним из основных преимуществ здесь является то, что вам не нужно распространять свои зависимости при распространении своего script. Единственным недостатком этого метода является то, что Jar должен находиться в репозитории Maven.
Ответ 5
Вы также можете попробовать Groovy Grape. Он позволяет использовать аннотации для изменения пути к классам. Его экспериментальный прямо сейчас, но довольно круто. См. http://groovy.codehaus.org/Grape
Ответ 6
То же, что и в Java.
Это пример запуска мониторинга состояния MySQL script. mysql.jar содержит соединитель MySQL, который я вызываю из script status.groovy.
groovy -cp mysql.jar status.groovy ct1
Ответ 7
Добавляя к @Patrick свой ответ, который мне очень помог, я недавно обнаружил еще один трюк.
Если вы добавите много кусков в путь к классам на одной строке, все может стать совершенно нечитаемым. Но вы можете сделать следующее!
#!/bin/bash
//bin/true && OPTS="-cp blah.jar -Dmyopt=value"
//bin/true && OPTS="$OPTS -Dmoreopts=value2"
//usr/bin/env groovy $OPTS "$0" [email protected]; exit $?
println "inside my groovy script"
Позвольте вашему воображению разобраться в том, насколько сложна командная строка, которую вы можете разрушить таким образом в управляемые части.
Маартен
Ответ 8
Ниже приведено сочетание решения Патрика, решение Maarteen Boekhold и комментарий foozbar, который работает как с обоими Linux и Cygwin:
#!/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" "[email protected]"; exit $?
import org.springframework.class.from.jar
//other groovy code
println 'Hello'
Как это работает:
-
//
является допустимым комментарием groovy, поэтому все команды bash игнорируются Groovy. -
//
вернет ошибку, но вывод ошибки перенаправляется на/dev/null
и поэтому не отображается. - bash выполняет команды, следующие за точкой с запятой, даже если предыдущая команда не удалась.
-
exec
заменяет текущую программу в текущем процессе, не открывая новый процесс. Таким образом, groovy выполняется в исходном script процессе (ps
показывает процесс как script, а не исполняемый файл groovy) - Оператор
exit $?
, следующий заexec groovy
, предотвращает попытку bash интерпретировать остальную часть script как bash script, а также сохраняет код возврата из groovy script.
Приведенный выше bash трюк более удобен в некоторых случаях, чем трюк RootLoader, поскольку вы можете использовать регулярные операторы импорта в script. Использование трюка RootLoader заставляет вас загружать все классы с использованием отражения. Это нормально в некоторых ситуациях (например, когда вам нужно загрузить драйвер JDBC), но неудобно в других.
Если вы знаете, что ваш script никогда не будет выполнен на Cygwin, то использование решения Patrick или Maarteen, скорее всего, приведет к немного лучшей производительности, потому что они избегают накладных расходов на создание и отбрасывание ошибки.
Ответ 9
Если вы хотите использовать его сразу перед объявлениями import
, это возможно так::):
// printEmployees.groovy
this.class.classLoader.rootLoader.addURL(
new URL("file:///C:/app/Dustin/product/11.1.0/db_1/jdbc/lib/ojdbc6.jar"))
import groovy.sql.Sql
sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:orcl", "hr", "hr",
"oracle.jdbc.pool.OracleDataSource")
sql.eachRow("SELECT employee_id, last_name, first_name FROM employees")
{
println "The employee name is ${it.first_name} ${it.last_name}."
}
Взято из этого статья javaworld.com.