그루비 스크립트에 항아리를 어떻게 포함합니까? [복제하다
문제
이 질문은 이미 여기에 답이 있습니다.
항아리에 라이브러리가 필요한 그루비 스크립트가 있습니다. 클래스 스팟에 어떻게 추가합니까? 스크립트를 실행하기를 원하므로 사용하고 있습니다. #!/usr/bin/env groovy
내 대본 상단에.
해결책
당신이 정말로 당신이 필요하다면, 런타임에 항아리를로드 할 수도 있습니다.
this.getClass().classLoader.rootLoader.addURL(new File("file.jar").toURL())
다른 팁
그루비 스크립트를 시작합니다 #!/usr/bin/env groovy
매우 중요한 한계가 있습니다. 추가 인수를 추가 할 수 없습니다. ClassPath를 구성 할 수 없으며 정의 또는 디버그에서 실행중인 Groovy가 없습니다. 이것은 아닙니다 그루비 발행, 그러나 Shebang의 제한 (#!
) 작품 - 모든 추가 인수는 단일 주장으로 취급됩니다. #!/usr/bin/env groovy -d
말하고 있습니다 /usr/bin/env
명령을 실행합니다 groovy -d
그럼 라틴 groovy
논쟁과 함께 d
.
이 문제에 대한 해결 방법이 있으며, 여기에는 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'
모든 마법은 처음 두 줄에서 발생합니다. 첫 번째 줄은 이것이 a라는 것을 알려줍니다 bash
스크립트. bash
실행을 시작하고 첫 번째 줄을 봅니다. ~ 안에 bash
#
의견을위한 것입니다 //
무너졌습니다 /
루트 디렉토리입니다. 그래서 bash
실행됩니다 /usr/bin/env groovy -cp extra.jar:spring.jar:etc.jar -d -Dlog4j.configuration=file:/etc/myapp/log4j.xml "$0" $@
그것은 우리의 모든 원하는 주장으로 그루비를 시작합니다. 그만큼 "$0"
우리 대본의 길입니다 $@
논쟁입니다. 이제 Groovy가 실행되고 처음 두 줄을 무시하고 Groovy 스크립트를보고 다시 나옵니다. bash
. bash
그런 다음 종료 (exit $?1
) Groovy의 상태 코드와 함께.
항아리를 $ home/.groovy/lib에 추가 할 수 있습니다.
내가 가장 좋아하는 방법은 그루비 포도입니다. 이들은 Maven Central 저장소에 액세스하고 참조 된 JAR을 다운로드 한 다음 클래스 스팟에 넣습니다. 그런 다음 다른 라이브러리처럼 라이브러리를 사용할 수 있습니다. 구문은 정말 간단합니다.
@Grab(group='com.google.collections', module='google-collections', version='1.0')
자세한 내용을 읽을 수 있습니다 여기. 여기서 가장 큰 장점은 스크립트를 배포 할 때 종속성을 배포 할 필요가 없다는 것입니다. 이 방법의 유일한 단점은 항아리가 Maven 저장소에 있어야한다는 것입니다.
그루비 포도를 시험해 볼 수도 있습니다. 주석을 사용하여 클래스 경로를 수정할 수 있습니다. 지금은 실험적이지만 꽤 시원합니다. 보다 docs.groovy-lang.org/.../grape
Java에서와 마찬가지로.
이것은 MySQL 상태 모니터링 스크립트를 실행하는 예입니다. mysql.jar에는 script status.groovy에서 호출하는 mysql 커넥터가 포함되어 있습니다.
Groovy -cp mysql.jar status.groovy ct1
아래는의 조합입니다 패트릭의 해결책, 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'
작동 방식 :
//
유효한 그루비 댓글이므로 모든 bash 명령은 Groovy에 의해 무시됩니다.//
오류가 반환되지만 오류 출력이/dev/null
따라서 표시되지 않습니다.- Bash는 이전 명령이 실패하더라도 세미콜론에 따라 명령을 실행합니다.
exec
새로운 프로세스를 포킹하지 않고 현재 프로세스에서 현재 프로그램을 대체합니다. 따라서 그루비는 원래 스크립트 프로세스 내에서 실행됩니다 (ps
프로세스를 그루비 실행 파일이 아닌 스크립트로 표시)- 그만큼
exit $?
다음 진술exec groovy
Bash가 스크립트의 나머지 부분을 Bash 스크립트로 해석하려고하지 않으며 Groovy 스크립트에서 리턴 코드를 보존합니다.
위의 배쉬 트릭은 경우에 따라 더 편리합니다. 루트 로더 트릭 스크립트 내에서 정기적 인 가져 오기 문을 사용할 수 있기 때문입니다. 루트 로더 트릭을 사용하면 반사를 사용하여 모든 클래스를로드해야합니다. 이것은 어떤 상황에서는 (예 : JDBC 드라이버를로드해야 할 때와 같은) 괜찮지 만 다른 상황에서는 불편합니다.
Cygwin에서 스크립트가 실행되지 않는다는 것을 알고 있다면 Patrick 's 또는 Maarteen의 솔루션을 사용하면 오류를 생성하고 버리는 오버 헤드를 피하기 때문에 약간 더 나은 성능을 얻을 수 있습니다.
@Patrick에 그의 대답을 더하면서 많은 도움이 되었기 때문에 최근에 또 다른 속임수를 발견했습니다.
한 줄의 클래스 경로에 많은 항아리를 추가하면 물건을 읽을 수 없게 될 수 있습니다. 그러나 당신은 다음을 할 수 있습니다!
#!/bin/bash
//bin/true && OPTS="-cp blah.jar -Dmyopt=value"
//bin/true && OPTS="$OPTS -Dmoreopts=value2"
//usr/bin/env groovy $OPTS "$0" $@; exit $?
println "inside my groovy script"
당신의 상상력이 얼마나 복잡한 명령 줄에 이런 식으로 분류 할 수 있는지에 대한 상상력을 활용하십시오.
MAARTEN
당신이 그것을 사용하고 싶다면 바로 앞 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's name is ${it.first_name} ${it.last_name}."
}
이것에서 가져 왔습니다 javaworld.com 기사.