문서의 이전 판입니다!
build.gradle
로 Eclipse 프로젝트를 가정하고 있다.apply plugin: 'java' apply plugin: 'eclipse' ext { javaVersion='1.6' } buildDir = 'build' repositories { mavenCentral() } dependencies { compile '원하는 모듈' testCompile group: 'junit', name: 'junit', version: '4.+' } task initSrc << { project.sourceSets*.allSource.srcDirTrees.flatten().dir.each { dir -> dir.mkdirs() } } sourceCompatibility = javaVersion targetCompatibility = javaVersion // 소스 인코딩 지정방법 1 [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' // 소스 인코딩 지정밥법 2 tasks.withType(Compile) { options.encoding = 'UTF-8' } /* Eclipse 관련 설정들 */ tasks.eclipse.dependsOn cleanEclipse tasks.eclipse.dependsOn initSrc eclipse { classpath { downloadSources = true defaultOutputDir = file("${buildDir}/classes/main") } }
src/main/java
, src/main/resources
src/test/java
, src/test/resources
build/*
buildDir
를 프로젝트에 상대적인 경로로 바꿔줄 수 있다. buildDir = 'target'
clean
: build 디렉토리 삭제compileJava
, compileTestJava
: 소스 컴파일assemble
: 컴파일 하고 jar 생성. 웹 프로젝트일 경우에는 war 생성. 단위 테스트 실행 안함.check
: 컴파일하고 단위테스트 실행.repositories { mavenCentral() } dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.+' }
// 저장소를 지정하고, uploadArchives { repositories { flatDir { dirs 'repos' } } }
gradle uploadArchives
명령으로 퍼블리싱한다.
자바 프로젝트의 기본 프로젝트 레이아웃은 다음과 같다.
src/main/java
: 실행 자바 소스src/main/resources
: 실행 리소스src/test/java
: 테스트 자바 소스src/test/resources
: 테스트 리소스src/소스셋/java
: 특정 소스 셋의 Java 소스src/소스셋/resources
: '특정 소스 셋의 리소스다음과 같은 의존성 설정(configurations)이 추가되다. 이 의존성 설정은 자바 플러그인의 태스크들에 의해 참조 된다.
이름 | 부모 | 사용하는 태스크 | 의미 |
---|---|---|---|
compile | - | compileJava | 컴파일 시점 의존성 |
runtime | compile | - | 실행시 의존성 |
testCompile | compile | compileTestJava | 테스트를 컴파일할 때 필요한 추가적인 의존성 |
testRuntime | runtime, testCompile | test | 테스트만 실행할 때 필요한 추가적인 의존성 |
archives | - | uploadArchives | 해당 프로젝트가 생성한 Artifact(jar 등) |
default | runtime | - | 이 프로젝트에서 기본으로 사용되는 의존성. 이 프로젝트의 실행시에 필요한 Artifact들과 의존성을 포함한다. |
소스 셋을 추가하면 다음과 같은 의존성 설정도 함께 추가된다.
이름 | 부모 | 사용하는 태스크 | 의미 |
---|---|---|---|
소스셋Compile | - | compile소스셋Java | 특정 소스셋의 컴파일시점 의존성 |
소스셋Runtime | 소스셋Compile | - | 특정 소스셋의 실행시 의존성 |
Gradle 문서 참조. JavaPluginConvention, BasePluginConvention 참조.
sourceSets
프라퍼티로 접근할 수 있다. SourceSetContainer 타입.println sourceSets.main.output.classesDir println sourceSets['main'].output.classesDir sourceSets { println "Sources Sets " + main.output.classesDir } sourceSets { main { println "Source Sets main " + output.classesDir } } sourceSets.all { println "Iterate all Source Sets : " + name }
// main java 소스셋의 디렉토리 추가 sourceSets { main { java { srcDir 'src/java' } resources { srcDir 'src/resources' } } }
저기서 main 은 SourceSet이다.
저기서 'java'와 'resources'는 SourceDirectorySet이며 srcDir()
메소드는 소스 디렉토리를 추가하는 것이다.
프라퍼티 이름 | Type | 기본값 | 설명 |
---|---|---|---|
name | String(read-only) | not null | 소스셋 이름 |
output | SourceSetOutput | not null | 소스셋의 출력 디렉토리. 컴파일된 클래스와 리소스를 저장할 곳 |
output.classesDir | File | buildDir/classes/name | 소스셋의 클래스를 생성할 디렉토리 |
output.resourcesDir | File | buildDir/resources/name | 소스셋의 리소스를 생성할 디렉토리 |
compileClasspath | FileCollection | compileSourceSet configuration | 소스를 컴파일할 때 사용할 클래스패스 |
runtimeClasspath | FileCollection | output + runtimeSourceSet configuration | 클래스 실행시의 클래스패스 |
java | SourceDirectorySet (read-only) | not null | 소스셋의 자바 소스파일들. *.java 파일만 포함호며 그 외 파일은 제외된다. |
java.srcDirs | Set<File>, Project.files()에서 사용할 수 있는 모든 값 | [projectDir/src/name/java] | 자바 소스 파일을 포함하고 있는 소스 디렉토리들, srcDir() 로 추가가능 |
resources | SourceDirectorySet (read-only) | not null | 소스셋의 리소스들. *.java 파일은 제외된다. 플러그인에 때라 제외되는 목록이 추가된다. |
resources.srcDirs | Set<File>, Project.files()에서 사용할 수 있는 모든 값 | [projectDir/src/name/resources] | 리소스를 포함하고 있는 소스 디렉토리들 |
allJava | SourceDirectorySet (read-only) | java | 모든 *.java 파일들. 플러그인에 따라 더 추가 될 수 있음 |
allSource | SourceDirectorySet (read-only) | resources + java | 모든 소스 파일들(리소스 + *.java). 플러그인에 따라 더 추가 될 수 있음. |
때로는 src/main/java
를 리소스에 포함시켜야 할 경우가 있다. 개발자들이 resources에 리소스를 넣지 않고 java에 넣고서 클래스와 리소스간의 결합성을 쉽게 파악할 수 있고자 할 경우가 있기 때문이다(iBATIS SqlMapper 사용하는 경우 등).
sourceSets { main { resources { srcDir "${project.projectDir}/src/main/java" // exclude "**/*.java" : 하지 말것. Gradle에서 문제 없지만 Eclipse에서 문제를 일으킴. } } }
sourceSets { }
블럭 안에 정의하면 된다.sourceSets { intTest } // 의존성 설정 dependencies { intTestCompile 'junit:junit:4.8.2' intTestRuntime 'org.ow2.asm.asm-all:4.0' }
gradle intTestClasses
형태로 실행.task intTestJar(type: Jar) { from sourceSets.intTest.output }
task intTestJavadoc(type: Javadoc) { source sourceSets.intTest.allJava }
task intTest(type: Test) { testClassesDir = sourceSets.intTest.output.classesDir classpath = sourceSets.intTest.runtimeClasspath }
// eclipse 플러그인 실행시 자동으로 기본 Java 디렉토리 구조를 생성하도록 한다. task baseDirs << { sourceSets.each { set -> set.java.srcDirs.each { dir -> if (!dir.exists()) dir.mkdirs() } set.resources.srcDirs.each { dir -> if (!dir.exists()) dir.mkdirs() } } if (!buildDir.exists()) buildDir.mkdirs() } tasks.eclipse.dependsOn baseDirs
태스크 프라퍼티 | 타입 | 기본값 |
---|---|---|
classpath | FileCollection | sourceSets.main.output + sourceSets.main.compileClasspath |
source | FileTree | sourceSets.main.allJava]] |
destincationDir | File | |
title | String | 프로젝트 이름과 버전 |
* StandardJavadocDocletOptions (Gradle API 1.10) 참조하여 javadoc 옵션들 지정.
task javadoc(type: Javadoc) { source subprojects.collect {project -> project.sourceSets.main.allJava } destinationDir = new File(buildDir, 'javadoc') // Might need a classpath classpath = files(subprojects.collect {project -> project.sourceSets.main.compileClasspath}) } }
ext { lombokVersion = '1.12.4' } configurations { lombok } dependencies { lombok "org.projectlombok:lombok:${lombokVersion}" } task delombok { ext.srcJava = 'src/main/java' ext.srcDelomboked = "${buildDir}/src-delomboked" inputs.files file(srcJava) outputs.dir file(srcDelomboked) doLast { // 보통은 configurations.runtime만으로 충분하지만, 가끔 provided 등의 사용자정의 configuration이 // 존재 할 경우 classpath에 존재하지 않는 라이브러리라서 경고를 보여줄 수 있으므로 // 모든 configurations의 의존성을 하나로 모아서 classpath로 지정한다. def allDependencies = configurations.lombok.asFileTree configurations.all { configuration -> allDependencies = allDependencies + configuration.asFileTree } // 구버전 Task class : lombok.delombok.ant.DelombokTask // 최신버전 Task class: lombok.delombok.ant.Tasks$Delombok ant.taskdef(name: 'delombok', classname: 'lombok.delombok.ant.Tasks$Delombok', classpath: configurations.lombok.asPath) ant.delombok(from: srcJava, to: srcDelomboked, verbose: true, encoding: 'UTF-8', classpath: allDependencies.asPath) } }
javadoc { dependsOn delombok source = fileTree(dir: delombok.srcDelomboked, includes: ['**/*.java', '**/*.html']) options.encoding = 'utf-8' } // 불필요한 리소스가 복사되는 경우에 대비해 java/html 파일만 include
태스크 프라퍼티 | 타입 | 기본값 |
---|---|---|
dir | File | buildDir |
태스크 프라퍼티 | 타입 | 기본값 |
---|---|---|
srcDirs | files()가 받을 수 있는 모든 값 | sourceSet.resources |
destinationDir | File | sourceSet.output.resourcesDir |
compileTestJava
에도 공통 적용된다.태스크 프라퍼티 | 타입 | 기본값 |
---|---|---|
classpath | FileCollection | sourceSet.compileClasspath |
source | FileTree files()가 받을 수 있는 모든 인자]] | sourceSet.java |
sourceCompatibility | String | Java 소스의 Java 언어 레벨 (…, 1.4,1.5,1.6,1.7 …) project.sourceCompatibilty |
targetCompatibility | Strign | Java 클래스의 Java 언어레벨 project.targetCompatibility |
destinationDir | File | sourceSet.output.classesDir |
options | CompileOptions | 컴파일 관련 각종 옵션 설정 |
options.useAnt=false
로 바꾸면 Ant를 건너뛰고 Gradle 기본 컴파일러로 수행한다.options.fork=true
로 설정하면 독립 컴파일러 프로세스가 뜨게 된다. 성능이 떨어질 수 있다.options
에서 소스 인코딩 등을 지정할 수 있다.아래 값들은 Java 플러그인을 적용한 뒤에 설정해야 한다. 그렇지 않으면 Java 플러그인이 값을 초기화 해 버릴 수도 있다. 아래 값들은 ext 블럭으로 만들면 “안” 된다.
compileJava.options.encoding = 'UTF-8' // 혹은 [compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
// project 단위 sourceCompatibility = '1.6' targetCompatibility = '1.6' // compileJava 단위 compileJava { sourceCompatibility = '1.6' targetCompatibility = '1.6' }
compileJava.options.compilerArgs = ['옵션1', ..]
test
태스크는 Test의 인스턴스이다.test.debug
프라퍼티를 true
로 설정하면 디버그모드로 실행되며 5005 포트로 디버깅할 수 있다.maxParallelForks
프라퍼티로 테스트 프로세스 갯수를 설정할 수 있다. 기본값은 1이다.(병렬 테스트 안함)org.gradle.test.worker
시스템 프라퍼티를 설정한다.forkEvery
프라퍼티로 몇개의 테스트를 수행한뒤에 프로세스를 재시작 할지 정할 수 있다. 단위 테스트가 JVM Heap을 너무 많이 소모할 경우 이 값을 작게준다. 기본은 재시작 안함.ignoreFailures
프라퍼티는 테스트 실패시 행위를 정의한다. 기본값은 false
이며 테스트가 실패하면 즉시 멈춘다. true
일 경우 테스트가 실패해도 멈추지 않고 다음으로 넘어간다.testLogging
프라퍼티는 테스트의 로깅 레벨을 설정한다. 기본적으로 모든 실패한 테스트에 대한 요약 메시지를 보여준다. TestLoggingContainer 참조.testLogging.showStandardStreams = true
설정 필요.cleanTest
태스크를 먼저 실행하고 테스트를 하면 된다.gradlew cleanTest test
gradle -D프라퍼티이름=값
형태로 지정한다.taskName.single=testNamePattern
형태를 지정하면 testNamePattern
에 일치하는 테스트만 실행된다.taskName
은 멀티프로젝트 패스 형태(:sub1:sub2:test
)로 기술하거나 그냥 태스크 이름만 기술해도 된다.testNamePattern
은 **/testNamePattern*.class
형태로 기술한다.gradle -Dtest.single=ThisUniquelyNamedTest test gradle -Dtest.single=a/b/ test gradle -DintegTest.single=*IntegrationTest integTest gradle -Dtest.single=:proj1:test:Customer build gradle -DintegTest.single=c/d/ :proj1:integTest
scanForTestClasses
를 false
로 하면 자동감지를 수행하지 않는다. 이 경우 명시적으로 포함/제외 시킨 클래스만 실행한다.scanForTestClasses=false
이면서 포함/제외 클래스를 명시하지 않으면 기본적으로 **/*Tests.class
와 **/*Test.class
를 실행하고, **/Abstract*.class
는 제외한다.@RunWith
어노테이션 적용@Test
어노테이션을 가진 메소드가 있는 클래스@Test
어노테이션을 가진 메소드가 있는 클래스*Test
와 *IntegrationTest
를 분리해서 실행하고자 하는 경우가 있을 수 있다.test { exclude '**/*IntegrationTest.class' } task integrationTest(type: Test, dependsOn: testClasses) { description = 'Integration test' group = 'verification' include '**/*IntegrationTest.class' testReportDir file("${buildDir}/reports/integration-test") } tasks.withType(Test) { // Test 들의 공통 설정 useJUnit() maxHeapSize '2048m' jvmArgs '-XX:MaxPermSize=256m' testLogging { events 'started', 'passed' } }
태스크 프라퍼티 | 타입 | 기본값 |
---|---|---|
testClassesDir | File | sourceSets.test.output.classesDir |
classpath | FileCollection | sourceSets.test.runtimeClasspath |
testResultsDir | File | testResultsDir |
testReportDir | File | testReportDir |
testSrcDirs | List<File> | sourceSets.test.java.srcDirs |
jvmArgs | List<String> | [], 문자열 배열로 JVM 옵션을 지정한다. |
maxHeapSize | String | null, '256m' 형태 |
systemProperty | 키, 값 | 키, 값 쌍을 인자로 테스트 수행 JVM의 시스템 프라퍼티 지정 |
include | String[] | [], '**/*IntgrationTest.class', 'org/foo/**', … |
exclude | String[] | [], '**/*IntgrationTest.class', 'org/foo/**', … |
test { testLogging { // set options for log level LIFECYCLE events "failed" exceptionFormat "short" showStandardStreams true // set options for log level DEBUG debug { events "started", "skipped", "failed" exceptionFormat "full" } } }
gradle build -x test
처럼 -x test
옵션을 준다.Creating a unit test report for subprojects
subprojects { apply plugin: 'java' // Disable the test report for the individual test task test { reports.html.enabled = false } } task testReport(type: TestReport) { destinationDir = file("$buildDir/reports/allTests") // Include the results from the `test` task in all subprojects reportOn subprojects*.test }
jar { archiveName = 'nameWhatIWant.jar' }
manifest
프라퍼티가 있다.MANIFEST.MF
파일이 함께 저장된다.jar { manifest { attributes("Implementation-Title": "Gradle", "Implementation-Version": version) } }
ext.sharedManifest = manifest { attributes("Implementation-Title": "Gradle", "Implementation-Version": version) } task fooJar(type: Jar) { manifest = project.manifest { from sharedManifest } }
Manifest
객체나 파일이 될 수 있다.task barJar(type: Jar) { manifest { attributes key1: 'value1' from sharedManifest, 'src/config/basemanifest.txt' from('src/config/javabasemanifest.txt', 'src/config/libbasemanifest.txt') { eachEntry { details -> if (details.baseValue != details.mergeValue) { details.value = baseValue } if (details.key == 'foo') { details.exclude() } } } } }
from
절에 기술한 순서에 따라 병합된다.eachEntry
를 통해 ManifestMergeDetails 객체를 받아서 조정 가능하다.writeTo
아니면 effectiveManifest
가 호출되는 시점에 늦은 초기화 방식으로 수행된다.jar.manifest.writeTo("$buildDir/mymanifest.mf")
Java 클래스를 실행할 때 Ant를 사용하는 방법과 JavaExec를 사용하는 방법이 있다.
project.javaexec()
메소드를 호출해도 된다. javaexec
메소드는 Closure를 인자로 받는데 거기 들어가는 내용은 JavaExec
설정과 같다.
Gradle Application Plugin도 참조한다.
// 외부 의존성 지정 필요시 configurations { newConfForJavaexec } dependencies { newConfForJavaexec "xxxx:xxx:1.1" // ... } task someTask(type: JavaExec) { main = 'xxx.yyy.MainClass' // 외부 의존성의 Java 클래스 실행시 classpath = configurations.newConfForJavaexec // 외부 jar가 아닌 현재 프로젝트의 Java 클래스 실행시 - 1번 방식 classpath = configurations.runtime classpath += sourceSets.main.output // 외부 jar가 아닌 현재 프로젝트의 Java 클래스 실행시 - 2번 방식 classpath = sourceSets.main.runtimeClasspath args '인자1', '인자2', ..... systemProperty 'simple.message', 'Hello ' }
classpath
는 FileCollection 객체이다.Gradle을 통해 실행되는 Java Application에 Gradle의 System Properties를그대로 전달하기 - Gradle Goodness: Pass Java System Properties To Java Tasks
// The run task added by the application plugin // is also of type JavaExec. tasks.withType(JavaExec) { // Assign all Java system properties from // the command line to the JavaExec task. systemProperties System.properties }