[Gradle] build.gradle 설정

해니·2023년 1월 27일
post-thumbnail



1. plugin 설정

  • plugin은 미리 구성해 놓은 task들의 그룹이며 , 특정 빌드 과정에 필요한 기본 정보를 포함하고 , 필요에 따라 정보를 수정하여 목적에 맞게 사용할 수 있음
    ex) 'gradle run' 태스크는 프로젝트에 'application' 플러그인을 추가해야 사용할 수 있고, 'gradle bootRun' 은 'org.springframework.boot' 플러그인에 포함되어 있음




apply plugin

  • 플러그인의 버전을 직접 지정할 수 없기 때문에, 특정 버전의 플러그인을 지정하여 추가하려면 다음과 같은 방식을 사용해야 함



buildscript {
    ext {
        springBootVersion = '2.4.5.RELEASE'
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java' 
apply plugin: 'application'
apply plugin: 'org.springframework.boot'



plugins {}

  • buildscript 부분과 plugin 부분을 plugins 블록 하나로 통합할 수 있음
  • 기본적으로 프로젝트 전체에 적용됨
    • 일부 서브 프로젝트에만 한정적으로 적용해야 할 경우 plugins 블록에서는 apply false를 선언하고, 사용할 서브 프로젝트에서만 apply plugin 구문을 명시함으로써 해당 플러그인의 적용 범위를 제한할 수 있음

  plugins {
  id 'java'
  id 'application' 
  id 'org.springframework.boot' version '2.4.5.RELEASE' apply false 
}

subprojects {
  if (name.startsWith('api')) {
    apply plugin: 'org.springframework.boot' 
  }
}





2. buildscript {}

  • buildscript는 빌드 시 가장 먼저 실행되는 블록

    • 소스 코드의 빌드 및 실행에 필요한 의존성 라이브러리과 레포지토리를 글로벌 레벨에서 정의
    • build.gradle 파일 그 자체를 위해, RPMs, Dockerfile 등을 빌드하는 데 필요한 의존성을 추가
  • build.gradle 스크립트에서 필요한 의존성은 buildscript 블록에 작성해야

  • buildscript 블록은 스크립트 최상단에 정의해야 함

    • buildscript 블록에 정의한 내용은 플러그인 설정에 영향을 미치는데, 작성 순서가 바뀌어 있으면 플러그인 설정을 핸들링할 수 없는 문제가 발생함
    • build.gradle을 작성할 때에는 buildscript 블록을 가장 먼저 작성해야 하며, 그 다음으로 plugins 블록을 작성해야 함

repositories

  • build.gradle이 들어있는 프로젝트에서 사용하는 라이브러리의 위치를 지정

  • jcenter(), mavenCentral(), google() 등 주로 인터넷에 있는 공개용 라이브러리 저장소를 사용함



dependencies

  • repository에서 jcenter, mavenCentral, google등의 외부 라이브러리 레파지토리를 지정했다면 해당 레파지토리에서 찾을 라이브러리 명을 입력해야 함





3. 저장소(repositories) 설정

  • Gradle 은 Maven Repository , JCenter , Ivy directory 등 다양한 저장소를 지원함
  • repositories{}에서 Gradle이 의존성 모듈을 가져올 저장소를 선언함
  • repositories{}에서 다운 받은 jar는 $USER_HOME/.gradle/caches/modules-2/files-2.1/ 경로에 캐시됨


// build.gradle
repositories {
	mavenLocal()		// Maven 로컬 저장소
    mavenCentral()	  // Maven 중앙 저장소
    maven{ url "http://ropo.company.com/maven" }
    jcenter()		// JCenter 저장소
}



💡 저장소 (repository)

  • 의존성을 제공하는 모듈들을 저장하는 장소
  • 로컬 저장소가 될 수도 있고 , 원격 저장소가 될 수도 있음
  • Gradle에게 어디서 의존성 모듈을 가져올건지 알려줘야 하는데, repository 선언을 통해 할 수 있음





4. sourceCompatibility

  • Java 버전과 일치하는 값으로 컴파일에서 사용하는 JDK 버전
  • 소스 코드에서 사용할 수 있는 Java 버전을 해당 버전 값으로 제한함
  • 컴파일 단계에서 에러를 감지하여, 실수로 더 높은 버전의 Java 기능을 사용하는 것을 방지함
  • Spring boot 프로젝트 생성 시에 sourceCompatibility는 자동으로 추가됨



💡 targetCompatibility

  • sourceCompatibility와 유사한 기능
  • 생성된 클래스 파일의 버전을 제어함
  • 프로그램에서 실행할 수 있는 가장 낮은 Java 버전을 의미함
  • 해당 버전 이상의 Java 버전을 사용해야 하며, 마찬가지로 컴파일 단계에서 에러를 감지함
  • Spring boot 프로젝트 생성 시 자동으로 추가되지 않으므로 개발자가 직접 추가해야 함





5. Runnable(fat) jar 생성

  • Runnable jar를 만들기 위해서는 메인클래스를 등록해줘야 함

// build.gradle

// Include dependent libraries in archive.
mainClassName = "com.company.application.Main"

jar {
  manifest {
    attributes "Main-Class": "$mainClassName"
  }

  from {
    configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
  }
}





6. 의존관계 설정

  • Gradle은 java의 의존성 관리를 위해 다양한 구성을 제공함

    • implementation : 프로젝트 컴파일 과정에서 필요한 라이브러리

    • providedComplie : 컴파일시에는 필요하지만 , 배포시에는 제외될 dependency를 설정함

    • providedRuntime : 런타임시에만 필요하고, 실행 환경에서 제공되는 dependency를 설정함

    • testImplementation : 테스트시에 필요한 dependency 관리

    • providedComplie와 providedRuntime은 war plugin이 설정된 경우에만 사용 가능함




💡 implementation vs api , complie

  • 오래된 Gradle 버전에는 implementation이 없어서 compile을 사용했고 , 6.X 이후 버전에서는 complie이 deprecated 되면서 complie 대신 api 키워드가 사용되게 되었다
  • Gradle에서는 api나 compile 사용을 권장하지 않음
    • 모듈에서 api나 complie을 사용해 라이브러리(패키징된 모듈)를 가져오게 되면 , 해당 라이브러리는 해당 모듈을 의존하는 모듈에도 가져와진다.
    • 모듈 사용 시, 모듈의 인터페이스만이 외부에 노출되어야하는데 라이브러리의 인터페이스까지 같이 노출되기 때문에 유지보수성 측면에서 좋지 않다.
    • 모듈에서 implementation을 사용해 가져오는 라이브러리는 해당 모듈을 의존하는 모듈에는 가져와지지 않는다.
      ex ) ModuleA에서 implementation을 이용해 라이브러리를 가져온 다음 , ModuleB에서 implementation을 이용해 라이브러리를 가져오면 라이브러리는 가져와지지 않는다. 라이브러리는 ModuleA에서 캡슐화되어 ModuleB에 노출되지 않는다 !








실제 프로젝트에서는..? 🧐


// all buildscript {} blocks must appear before any plugins {} blocks in the script

// 내용이 없을 경우 생략 가능
buildscript {
    repositories {
        jcenter() // 인터넷의 jcenter 레파지토리 사용  (https://bintray.com/bintray/jcenter)
    }

}


plugins {
    id 'java-library'
    id 'com.github.johnrengelman.shadow' version '6.1.0'
}
  
// In this section you declare where to find the dependencies of your project
repositories {
    // Use jcenter for resolving your dependencies.
    // You can declare any Maven/Ivy/file repository here.
    jcenter() // 기본 레파지토리

}
  

// JAVA 1.8 사용
sourceCompatibility = 1.8

  
dependencies {
  
    // https://mvnrepository.com/artifact/com.google.cloud/google-cloud-speech
	compileOnly('com.google.cloud:google-cloud-speech:1.29.2')
    
    // https://mvnrepository.com/artifact/com.google.cloud/google-cloud-texttospeech
	implementation 'com.google.cloud:google-cloud-texttospeech:1.1.0'
    
    // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
	testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.7.0'
	
	// https://mvnrepository.com/artifact/net.sourceforge.argparse4j/argparse4j
	implementation group: 'net.sourceforge.argparse4j', name: 'argparse4j', version: '0.8.1'

    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'
  
  
}
  
  
  • java-library
    • Java 라이브러리에 대한 특정 지식을 제공 하여 Java 플러그인( java) 의 기능을 확장함
    • Java 라이브러리는 소비자(즉, Java 또는 Java 라이브러리 플러그인을 사용하는 다른 프로젝트)에게 API를 노출함
    • api는 라이브러리 소비자에게 전이적으로 노출되며, 이와 같이 소비자의 컴파일 클래스 경로에 나타남
    • implementation은 소비자에게 노출되지 않으므로 소비자의 컴파일 클래스 경로로 누출되지 않는다
  • ShadowJar
    • 패키지 재배치를 지원하는 fat/uber JAR을 생성하기 위한 Gradle 플러그인












출처
https://blog.naver.com/sqlpro/222665643369
https://willbesoon.tistory.com/93
https://docs.gradle.org/current/userguide/java_library_plugin.html
https://velog.io/@billion109/플링크-Gradle-Jar-빌드시-생기는-에러-Gradle-ShadowJar-만들기
https://kotlinworld.com/317

profile
💻 ⚾️ 🐻 이전했어요..! ➡️ https://dev-haeni.tistory.com/

0개의 댓글