사용자 도구

사이트 도구


gradle:organizing_build_logic

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
gradle:organizing_build_logic [2012/10/06 16:26]
kwon37xi [외부 빌드 실행]
gradle:organizing_build_logic [2015/09/22 17:54] (현재)
kwon37xi [apply]
줄 74: 줄 74:
  
   * ''buildSrc''의 기본 빌드 스크립트<code groovy>   * ''buildSrc''의 기본 빌드 스크립트<code groovy>
-// build.gralde이 없어도 아래 빌드 스크립트가 존재하는 것으로 간주한다.+ 
 +// --build.gralde이 없어도 아래 빌드 스크립트가 존재하는 것으로 간주한다.-- 
 +// 1.6 버전에서는 명시적으로 필요한 것으로 보인다.
 apply plugin: 'groovy' apply plugin: 'groovy'
 dependencies { dependencies {
줄 84: 줄 86:
 이 말은 ''buildSrc''에 기본 Java/Groovy 프로젝트를 구성할 수 있다는 뜻이다. [[gradle:java|Gradle Java Plugin]], [[gradle:groovy|Gradle Groovy Plugin]] 이 말은 ''buildSrc''에 기본 Java/Groovy 프로젝트를 구성할 수 있다는 뜻이다. [[gradle:java|Gradle Java Plugin]], [[gradle:groovy|Gradle Groovy Plugin]]
  
-좀 더 복잡한 것이 필요하다면 자신만의 ''build.gradle''을 만들면 된다. Gradle은 기본 빌드 스크립트를 ''build.gradle''이 있건 없건 무조건 적용한다. 즉, 빌드 스크립트에는 기본값 외에 다른 것만 정의하면 된다.+좀 더 복잡한 것이 필요하다면 자신만의 ''build.gradle''을 만들면 된다. <del>Gradle은 기본 빌드 스크립트를 ''build.gradle''이 있건 없건 무조건 적용한다. 즉, 빌드 스크립트에는 기본값 외에 다른 것만 정의하면 된다.</del> 1.6 버전에서는 기본 설정도 함께 넣어야 하게 바뀐 것 같다.
  
   * ''buildSrc/build.gradle''<code groovy>   * ''buildSrc/build.gradle''<code groovy>
 +apply plugin: 'groovy'
 repositories { repositories {
     mavenCentral()     mavenCentral()
줄 94: 줄 96:
 // gradle과 groovy에 관한 의존성은 추가할 필요가 없다. // gradle과 groovy에 관한 의존성은 추가할 필요가 없다.
 dependencies { dependencies {
 +    compile gradleApi()
 +    groovy localGroovy()
     testCompile group: 'junit', name: 'junit', version: '4.8.2'     testCompile group: 'junit', name: 'junit', version: '4.8.2'
 } }
줄 104: 줄 108:
 } }
 </code> </code>
 +
 +===== JDBC Driver 로딩 못하는 문제 =====
 +  * Gradle 1.6에서 ''buildSrc''의 커스텀 태스크/플러그인 프로젝트에 지정된 JDBC Driver 클래스를 못 찾는 문제가 있다.(''No suitable driver found for jdbc:...'')
 +  * http://stackoverflow.com/questions/6329872/how-to-add-external-jar-files-to-gradle-build-script ''buildSrc/build.gradle'' <code groovy>
 +repositories {
 +    mavenCentral()
 +}
 +configurations {
 +    driver
 +}
 +dependencies {
 +    driver group: 'mysql', name: 'mysql-connector-java', version: '5.1.16'
 +}
 +
 +URLClassLoader loader = GroovyObject.class.classLoader
 +configurations.driver.each {File file ->
 +    loader.addURL(file.toURL())
 +}
 +
 +// JDBC Driver 사용하는 코드 혹은 custom task/plugin 제작
 +</code>
 +
 ===== 공유 스크립트 ===== ===== 공유 스크립트 =====
 [[:gradle|gradle]]에서 "외부 빌드 스크립트로 프로젝트 구성하기" 참조. [[:gradle|gradle]]에서 "외부 빌드 스크립트로 프로젝트 구성하기" 참조.
 ===== 커스텀 태스크 ===== ===== 커스텀 태스크 =====
-[[gradle:customtask|Custom Task]] 참조.+[[gradle:customtask|Gradle Custom Task]] 참조.
 ===== 커스텀 플러그인 ===== ===== 커스텀 플러그인 =====
 [[gradle:customplugins|Gradle Custom Plugins]] 참조. [[gradle:customplugins|Gradle Custom Plugins]] 참조.
줄 128: 줄 154:
 hello from the other build. hello from the other build.
 </code> </code>
-===== 외부 라이브러리 =====+===== 빌드 스크립트 전용 외부 라이브러리 ===== 
 +빌드 스크립트가 외부 라이브러리를 필요로 한다면 ''buildScript()'' 메소드를 사용하여 빌드 스크립트 자체의 스크립트 클래스패스에 추가하면 된다. 빌드 스크립트 클래스패스를 지정하는 클로저를 인자로 전달한다.
  
 +  * 빌드 스크립트의 외부 의존성 지정하기  ''build.gradle'' <code groovy>
 +buildscript {
 +    repositories {
 +        mavenCentral()
 +    }
 +    dependencies {
 +        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2' // classpath 구성 사용
 +    }
 +}
 +</code>
 +
 +''buildScript()''메소드에 전달된 클로저는 [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/initialization/dsl/ScriptHandler.html|ScriptHandler]]의 인스턴스를 구성한다.
 +
 +빌드 스크립트의 클래스패스는 **''classpath''** 구성을 사용하여 지정한다. 여기서는 프로젝트 의존성을 제외한 모든 의존성을 지정할 수 있다.
 +
 +빌드 스크립트 클래스패스를 지정한 위에는 빌드스크립트에서 해당 클래스를 마음대로 사용할 수 있다.
 +
 +  * 외부 의존 클래스 사용하는 빌드 스크립트 ''build.gradle'' <code groovy>
 +import org.apache.commons.codec.binary.Base64
 +
 +buildscript {
 +    repositories {
 +        mavenCentral()
 +    }
 +    dependencies {
 +        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
 +    }
 +}
 +
 +task encode << {
 +    def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
 +    println new String(encodedString)
 +}
 +</code>
 +  * 실행하면 <code>
 +> gradle -q encode
 +aGVsbG8gd29ybGQK
 +</code>
 +
 +  * 멀티 프로젝트에서는 프로젝트 빌드 스크립트의 의존성이 모든 서브프로젝트에도 적용된다.
 +  * 멀티 프로젝트에서 최상위 프로젝트의 ''buildscript''에 repository를 추가해도, 하위 프로젝트에서 다시 ''buildscript'' 구문을 넣고 의존성을 지정하면 하위 프로젝트의 **buildscriptt** 구문에 repository를 재지정해야 한다.
 +===== Ant 의존성 추가 =====
 +빌드 스크립트의 외부 의존성 추가 방식으로는 Ant에 의존성을 추가할 수 없다.
 +
 +  * Ant에 의존성 추가 ''build.gradle'' <code groovy>
 +configurations {
 +    ftpAntTask
 +}
 +
 +dependencies {
 +    // ant-commons-net의 maven pom.xml이 잘못돼 있어서 ant-commons-net의 추가 의존성을 직접 지정해줬다.
 +    ftpAntTask("org.apache.ant:ant-commons-net:1.8.4") {
 +        module("commons-net:commons-net:1.4.1") {
 +            dependencies "oro:oro:2.0.8:jar"
 +        }
 +    }
 +}
 +
 +task ftp << {
 +    ant {
 +        taskdef(name: 'ftp',
 +                classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
 +                classpath: configurations.ftpAntTask.asPath) // 여기서 추가된 클래스패스 사용!
 +        ftp(server: "ftp.apache.org", userid: "anonymous", password: "me@myorg.com") {
 +            fileset(dir: "htdocs/manual")
 +        }
 +    }
 +}
 +</code>
 +
 +===== apply =====
 +''apply from: 'some.gradle'''로 외부 Gradle 스크립트를 적용할 수 있다. 이때 파일 대신 URL을 적어도 된다. [[http://mrhaki.blogspot.kr/2012/10/gradle-goodness-init-script-for-adding.html|인트라넷 URL을 통해 전사 공통 자바 소스 스타일 검사기능 추가하는 방법]]
 +
 +<code groovy>
 +apply from: 'http://intranet/source/quality.gradle'
 +</code>
 +
 +이 방식을 사용할 경우 [[ci:jenkins|Jenkins]]등의 CI에서 동시 빌드시에 외부 리소스에 대한 락이 걸리는 상황이 발생한다.[[http://issues.gradle.org/browse/GRADLE-2795|[GRADLE-2795] Gradle locks the global script cache during the entire build, causing subsequent builds to fail if scripts change]]
 +아래와 유사한 오류가 발생할 것이다.
 +<code>
 +A problem occurred evaluating script.
 +Could not open buildscript class cache for script 'http://.../?p=build-core;a=blob_plain;f=repository-utils.gradle;hb=HEAD' (/home/build/.gradle/caches/1.6/scripts/_p_build_core_a_blob_plain_f_r_4n9gdhqrjd4inp4c6jive7ql9c/DefaultScript/buildscript).
 +Timeout waiting to lock buildscript class cache for script 'http://.../?p=build-core;a=blob_plain;f=repository-utils.gradle;hb=HEAD' (/home/build/.gradle/caches/1.6/scripts/_p_build_core_a_blob_plain_f_r_4n9gdhqrjd4inp4c6jive7ql9c/DefaultScript/buildscript). 
 +It is currently in use by another Gradle instance.
 +Owner PID: unknown
 +Our PID: 15314
 +Owner Operation: unknown
 +Our operation:
 +Lock file: /home/build/.gradle/caches/1.6/scripts/_p_build_core_a_blob_plain_f_r_4n9gdhqrjd4inp4c6jive7ql9c/DefaultScript/buildscript/cache.properties.lock
 +</code>
 +이 때 해결책은 빌드 스크립트 URL의 맨 뒤에 Jenkins Job의 이름을 넣어주는 것이다. 마지막의 ''**${java.net.URLEncoder.encode(System.getenv()['JOB_NAME'] ?: 'NOJOB', 'UTF-8')}**'' Job 마다 서로 다른 build script Cache를 생성하여 Lock 충돌이 방지된다.
 +<code groovy>
 +apply from: "http://server/epository-utils.gradle?jn=${java.net.URLEncoder.encode(System.getenv()['JOB_NAME'] ?: 'NOJOB', 'UTF-8')}"
 +</code>
 +
 +''JOB_NAME'' 대신 ''Math.random()''사용시 계속해서 빌드 스크립트 캐시가 서로 다른이름으로 생성되어 파일 갯수가 증가하게 된다.
 +''/home/[username]/.gradle/caches/[version]/scripts/*'' 디렉토리를 cron 등으로 주기적으로 정리해줘야한다. 아래는 하루에 한 번씩 어제날짜의 캐시 디렉토리를 삭제하는 Unix script.
 +
 +<code sh>
 +find /home/[user]/.gradle/caches/*/scripts -maxdepth 1 -mindepth 1 -mtime +1 -type d -exec rm -rf {} \;
 +</code>
gradle/organizing_build_logic.1349508376.txt.gz · 마지막으로 수정됨: 2012/10/06 16:26 저자 kwon37xi