티스토리 뷰

728x90
반응형

Goals

  • 빌드(Build)란?
  • Maven이란?
  • Gradle이란?
  • Maven과 Gradle의 차이

 

빌드(Build)란?


먼저 소프트웨어에서 말하는 빌드란 무엇인가?

소프트웨어 빌드(software build)는 소스 코드 파일을 컴퓨터나 휴대폰에서 실행할 수 있는 독립(standalone) 소프트웨어 가공물로 변환하는 과정을 말하거나 그에 대한 결과

우리가 코딩을 하고, 실행을 할 때 빌드를 거친 뒤에 실행이 되는데, JAVA를 예로 들면, .java 파일을 JVM에서 실행 가능한 바이트 코드 덩어리인 .class 파일로 변환하는 컴파일 과정도 빌드의 부분 집합이다.

또한, 여러개로 분리된 소스파일들이 컴파일 된 결과물에서 최종 실행가능한 파일을 만들기 위해 필요한 부분을 찾아서 연결해주는 작업인 정적링크 과정도 빌드 과정 중 하나다.

그리고 이 결과물들을 최종적으로 패키징하여 배포 가능한 형태로 만드는 모든 일련의 과정이 빌드다.

💡 빌드(build) = 컴파일(compile) + 정적링크(link) + 패키징 + 배포 + a

따라서 빌드를 한다는 것은 수 많은 일련의 과정을 거쳐야 하며, 최대한의 오류를 줄이기 위한 테스트가 필요하고, 대부분 비슷한 프로세스를 거치는 반복 작업이기 때문에 자동화의 필요성이 대두되는 것이다.

빌드 자동화 툴(Build Automation Tool)

빌드 자동화 툴은 소프트웨어 개발 프로세스에서 코드를 빌드하고 테스트, 배포하는 작업을 자동화하는 도구다. 개발자는 수동으로 수행해야 할 반복적인 작업을 자동화하여 개발 효율성을 높이고, 오류 발생 가능성을 줄이며, 일관된 빌드 환경을 구축할 수 있다.

MavenGradle은 모두 Java 애플리케이션 빌드 도구다. 둘 다 프로젝트 빌드 및 종속성 관리를 자동화하여 Java 애플리케이션 개발자들이 빠르고 효율적인 방식으로 애플리케이션을 빌드하고 배포할 수 있도록 도와준다.

아래는 배포 속도를 높여주는 상위 10개의 빌드 자동화 툴을 소개하는 포스팅

https://www.softwaretestinghelp.com/best-build-automation-software-tools/

JAR vs WAR

Java에서는 빌드 결과 산출물로 JAR(Java Archive)WAR(Web Application Archive)가 있다. 둘 다 Java 애플리케이션을 패키징 하는데 사용되는 파일 형식다.

.jar 파일은 Java 애플리케이션이 동작할 수 있도록 자바 프로젝트를 압축한 파일로, 하나 이상의 Java 클래스 파일, 리소스 파일 및 메타 데이터를 포함할 수 있다. 주로 라이브러리, 유틸리티 및 독립 실행 형 애플리케이션을 패키징하는 데 사용된다.

반면에, .war 파일은 웹 애플리케이션의 구성 파일, JSP(Java Server Pages) 파일, HTML, JavaScript, CSS 및 클래스 파일 등의 컴포넌트를 포함한다. 최종적으로 웹 애플리케이션 서버(Web Application Server)에서 배포된다.

WAR도 JAR 파일의 일종이지만, JAR은 JRE만 있어도 실행 가능한데 반해, WAR은 별도의 웹 서버 or 웹 컨테이너가 필요하며, 사전 정의된 구조(WEB-INF, META-INF)를 따라야 한다.

JAR, WAR은 파일 애플리케이션 리소스를 패키징 하는 방법에 차이가 있을 뿐이다. JSP를 사용하여 화면을 구성해야 하거나, 외장 WAS를 이용할 계획이 있어서 WAR을 써야만 하는 경우가 아니라면 어떤 걸 사용하지는 개발자의 판단이라고 한다.

하지만 Spring Boot에서 가이드 하는 표준은 JAR이므로 Spring Boot를 사용한다면 이를 따르는 것이 좋다.

(이 이상의 자세한 내용은 공식 문서를 참고)

Maven이란?


공식 문서에서는 Maven을 아래와 같이 소개한다.

지식 축적을 의미하는 이디시어인 Maven은 Jakarta Turbine 프로젝트에서 빌드 프로세스를 단순화하려는 시도로 시작되었습니다. (생략) 우리는 프로젝트를 빌드하는 표준 방법, 프로젝트 구성 항목에 대한 명확한 정의, 프로젝트 정보를 게시하는 쉬운 방법, 여러 프로젝트에서 JAR을 공유하는 방법을 원했습니다. (생략) Java 개발자의 일상적인 작업을 더 쉽게 만들고 일반적으로 Java 기반 프로젝트를 이해하는 데 도움이 되는 무언가를 만들었기를 바랍니다.

요약해 보면, Maven은 Java 기반 프로젝트를 관리하기 위한 빌드 도구로써, 빌드 프로세스를 쉽게 만들기 위해 균일한 빌드 시스템을 제공한다. 거기에 프로젝트 문서화 등을 통해 양질의 프로젝트 정보를 제공함으로써 프로젝트 이해도 높일 수 있다.

프로젝트 구조

my-app/
├── src/
│   ├── main/
│   │   ├── java/             # 애플리케이션 소스 코드
│   │   ├── resources/        # 애플리케이션 리소스 (설정 파일, 정적 파일 등)
│   │   └── webapp/           # 웹 애플리케이션 리소스 (JSP, HTML 등) - 웹 프로젝트에서 사용
│   └── test/
│       ├── java/             # 테스트 소스 코드
│       └── resources/        # 테스트 리소스 (테스트용 설정 파일 등)
├── target/                   # 빌드 결과물이 위치하는 디렉토리 (JAR, WAR, 클래스 파일 등)
│   ├── classes/              # 컴파일된 클래스 파일
│   ├── test-classes/         # 컴파일된 테스트 클래스 파일
│   └── ...                   # 기타 빌드된 아티팩트 (JAR, WAR 등)
├── pom.xml                   # Maven 프로젝트의 설정 파일

Maven은 표준화된 디렉토리 구조를 강제한다. POM 파일에서 <build> 섹션을 통해 구조를 변경할 수 있지만, 기본 구조를 따르는 것이 일반적이다.

POM(Project Object Model)

Maven은 POM(Project Object Model) 파일을 사용하여 프로젝트를 관리한다. POM 파일은 프로젝트에 대한 정보와 빌드 설정 정보, 의존성 라이브러리 정보 등을 담고 있어 POM 파일을 기반으로 프로젝트 빌드를 수행한다. 이 파일은 xml 파일로 프로젝트 최상위 디렉토리에 생성되어 pom.xml만 보면 프로젝트의 모든 설정, 의존성 등을 알 수 있다.

라이브러리 저장소(Repository)

Maven은 미리 정의된 라이브러리 저장소(Repository)를 사용하여 의존성 라이브러리를 다운로드하고 관리한다. 이를 통해 개발자는 직접 라이브러리를 다운로드하고 관리할 필요 없이, Maven을 통해 손쉽게 필요한 라이브러리를 가져올 수 있다.

빌드 라이프 사이클(Build Lifecycle)

Maven은 표준 빌드 라이프 사이클(Build Lifecycle)을 제공하여 개발자가 일관된 방식으로 프로젝트를 빌드할 수 있도록 돕는다.

Maven은 빌드 라이프 사이클을 실행할 때 특정 플러그인(Plugin)을 사용한다. 플러그인은 빌드 과정에서 필요한 특정 작업을 수행하도록 지원하며, 개발자가 직접 플러그인을 작성하여 사용할 수도 있다.

default Lifecycle은 아래 단계로 구성

  • validate - 프로젝트가 올바른지 확인하고 필요한 모든 정보를 사용할 수 있는 지 확인
  • compile - 프로젝트의 소스 코드 컴파일
  • test - 적절한 단위 테스트 프레임워크를 사용하여 컴파일된 소스 코드를 테스트
  • package - 컴파일된 코드를 가져와 JAR과 같은 배포 가능한 형식으로 패키징
  • verify - 통합 테스트 결과에 대한 모든 검사를 실행하여 품질 기준을 충족하는지 확인
  • install - 패키지를 로컬 저장소에 설치하는 단계
  • deploy - 다른 개발자 및 프로젝트와 공유할 수 있도록 최종 패키지를 원격 저장소에 복사

Gradle이란?


이번에는 gradle에 대한 공식 문서의 설명이다.

Gradle은 거의 모든 유형의 소프트웨어를 빌드할 수 있을 만큼 유연한 오픈 소스 빌드 자동화 도구입니다. Gradle은 빌드하려는 대상이나 빌드 방법에 대해 거의 가정하지 않습니다. 이것은 Gradle을 특히 유연하게 만듭니다.

gradle은 유연함(flexible)을 많이 강조하고 있는 것으로 보인다. 이는 Gradle이 특정 빌드 라이프 사이클을 따르지 않고, 빌드 스크립트를 자유롭게 작성할 수 있으며, 특정 플러그인을 사용하지 않고도 다양한 작업을 수행할 수 있기 때문이다.

프로젝트 구조

my-app/
├── src/
│   ├── main/
│   │   ├── java/             # 애플리케이션 소스 코드
│   │   ├── resources/        # 애플리케이션 리소스 (설정 파일, 정적 파일 등)
│   │   └── webapp/           # 웹 애플리케이션 리소스 (JSP, HTML 등) - 웹 프로젝트에서 사용
│   └── test/
│       ├── java/             # 테스트 소스 코드
│       └── resources/        # 테스트 리소스 (테스트용 설정 파일 등)
├── build/                    # 빌드 결과물이 위치하는 디렉토리 (JAR, WAR, 클래스 파일 등)
│   ├── classes/              # 컴파일된 클래스 파일
│   ├── test-classes/         # 컴파일된 테스트 클래스 파일
│   └── ...                   # 기타 빌드된 아티팩트 (JAR, WAR 등)
├── build.gradle              # Gradle 빌드 스크립트 (Groovy DSL)
├── settings.gradle           # (선택 사항) 멀티 프로젝트 설정 파일
├── gradle.properties         # (선택 사항) 프로젝트 속성 파일

Gradle은 기본적으로 Maven과 유사한 프로젝트 구조를 따르고 있지만, 개발자의 편의대로 변경하는 것을 쉽게 허용한다.

sourceSets {
    main {
        java {
            srcDirs = ['src/main/kotlin']  # 소스 디렉토리 변경
        }
        resources {
            srcDirs = ['src/main/assets']  # 리소스 디렉토리 변경
        }
    }
}

유연한 빌드 스크립트, DSL(Domain Specific Language)

Gradle은 그루비(Groovy) 언어 기반의 DSL(Domain Specific Language)을 사용하여 빌드 스크립트를 자유롭게 작성할 수 있다. 때문에 Java 개발자들이 보다 쉽게 이해할 수 있다.

build.gradle 파일에 의존성이나 플러그인 설정 등과 같은 빌드에 필요한 설정을 하게 된다. 빌드 작업 외에도 린트, 코드 포맷팅, 문서 생성 등 다양한 작업을 처리할 수 있어 개발 생산성을 높일 수 있다.

💡 Groovy는 Java 가상 머신에서 실행되는 스크립트 언어다. Java와는 달리 소스 코드를 컴파일 할 필요가 없다. 또한 Java와 호환되고, Java 클래스 파일을 그대로 Groovy 클래스로 사용할 수도 있다.

높은 성능

Gradle은 빌드 작업을 병렬 처리하여 빌드 시간을 단축 시킬 수 있으며, 빌드 캐시를 사용하여 이전에 빌드된 작업을 재 사용할 수 있다.

예를 들어, 이전에 20개의 라이브러리를 사용하다가 5개의 라이브러리를 추가하거나, 5개의 라이브러리를 교체하면, 해당 변경 사항만 다시 재 컴파일 시킨다.

확장성

Gradle은 다양한 플러그인을 제공하며, 사용자가 직접 플러그인을 작성할 수도 있다. 또한, 기존의 Maven 리포지토리 외에도 JCenter, Google Maven 등 다양한 리포지토리를 지원한다.

멀티 프로젝트 빌드 지원

Gradle은 멀티 프로젝트 빌드를 지원하며, 다양한 프로젝트 간의 의존성 관리를 쉽게 처리할 수 있다.

안드로이드 앱 빌드 지원

Gradle은 안드로이드 앱 개발에서도 널리 사용되며, 안드로이드 스튜디오(Android Studio)에서 기본적으로 지원된다.

Maven과 Gradle의 차이


상대적으로 Maven보다 Gradle이 늦게 나왔기 때문에 Maven보다 여러 방면에서 우수한 면을 보일 수 밖에 없다. 그래서 인지, Gradle 공식 문서에서는 Maven과 비교하는 글도 찾아볼 수 있다.

둘의 차이점이라기 보단 Gradle이 어떤 부분에서 Maven보다 우수한 지, 대표적으로 몇 가지만 알아보겠다.

XML vs Groovy

Maven은 XML 기반의 프로젝트 설정 파일을 사용하며, Gradle은 Groovy 스크립트를 사용한다. Gradle의 Groovy 스크립트는 Maven의 XML보다 간결하고 가독성이 좋다.

아래는 Maven 설정 파일인 pom.xml의 예시

<project xmlns="<http://maven.apache.org/POM/4.0.0>"
         xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"
         xsi:schemaLocation="<http://maven.apache.org/POM/4.0.0>
                             <http://maven.apache.org/xsd/maven-4.0.0.xsd>">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

위를 Gradle로 바꾸면 아래와 같다.

build.gradle

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.0.0'
	id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
	useJUnitPlatform()
}

훨씬 가독성이 좋고 간결해 진 코드를 확인할 수 있다.

성능

Gradle은 Maven보다 빌드 성능이 우수하다. 아래는 Gradle 공식 문서에서 3개의 시나리오에 걸쳐 Maven과 비교한 빌드 속도다.

Gradle은 거의 모든 시나리오에서 최소 2배 더 빠르다(빌드 캐시를 사용하는 대규모 빌드의 경우 100배 더 빠름)

이러한 차이가 나는 이유에는 3가지가 있다고 설명한다.

  • Incrementality: Gradle은 작업의 입력과 출력을 추적해 필요한 항목만 실행하고, 가능한 변경된 파일만 처리하여 불필요한 작업을 피합니다.
  • Build Cache: 두 개 이상의 빌드가 실행될 때, 동일한 파일이 있으면, 다른 Gradle 빌드 결과를 재 사용합니다.
  • Gradle Daemon: 메모리에서 빌드 정보를 "hot" 상태로 유지하는 수명이 긴 프로세스입니다. 따라서 최초의 빌드 이후에는 빌드 시간이 매우 단축됩니다.

플러그인 지원

Maven은 플러그인 시스템이 내장되어 있는 반면, Gradle은 다양한 플러그인을 지원한다. Gradle의 플러그인은 Java, Android, Groovy, Scala 및 기타 언어를 사용하여 빌드 및 테스트를 자동화할 수 있다.

Reference

728x90
반응형
댓글