Подтвердить что ты не робот

Как включить банки в groovy script?

У меня есть groovy script, которому нужна библиотека в банке. Как добавить это в путь к классам? Я хочу, чтобы script был исполняемым, поэтому я использую #!/usr/bin/env groovy в верхней части моего script.

4b9b3361

Ответ 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.