빌드 관리 도구
빌드
- 소스 코드 파일을 컴파일에서 실행할 수 있는 가공물로 변환하는 과정 또는 결과물
- 우리가 작성한 소스코드(java), 프로젝트에서 쓰인 각각의 파일 및 자원 등(.xml, jpa, jpg, properties)을 jvm이나 톰캣 같은 WAS가 인식할 수 있는 패키징하는 과정 및 결과물이라고 할 수 있다.
- 컴파일된 코드를 실제 실행할 수 있는 상태로 만드는 일(Compile + 그 외 작업)
빌드 관리 도구
- 소스 코드를 컴파일하고 테스트하며 정적 분석 등을 수행하여 실행 가능한 애플리케이션을 자동으로 생성하는 프로그램이다.
- 계속해서 늘어나는 라이브러리를 자동으로 추가 및 관리하고, 프로젝트를 진행하면서 시간이 지남에 따라 라이브러리의 버전을 자동으로 동기화한다.
초기의 Java빌드 도구로는 Apache Ant를 많이 사용했지만 스크립트 작성도 많고, 라이브러리 의존 관리가 되지 않는다는 불편함으로 최근에는 Maven과 Gradle이 많이 쓰인다.
수행하는 작업
- 종속성 다운로드
- 소스코드를 바이너리코드로 컴파일
- 바이너리 코드를 패키징
- 테스트 실행
- 프로덕션 시스템에 배포
Maven
프로젝트 관리 및 이해 도구이다. 프로젝트 객체 모델(POM) 개념을 기반으로, Maven은 중앙 정보에서 프로젝트의 빌드, 보고 및 문서를 관리할 수 있다.
지식의 축적자를 의미하는 이디시어로 자카르타 터빈 프로젝트의 빌드 프로세스를 간소화하려는 시도로 시작되었다.
- Ant이후에 나온 자바 빌드 도구로 자동으로 라이브러리와 의존성을 관리하는 기능이 있다.
- Ant와 마찬가지로 XML 스크립트를 기반으로 하며, pom.xml 파일로 의존성을 관리한다.
- Maven에서는 라이프 사이클 개념이 도입되어 빌드 순서 등을 정의 할 수 있다.
목표
Maven의 주된 목표는 개발자가 프로젝트의 현재 상태를 빠르고 쉽게 이해할 수 있도록 돕는 것이다.
- 빌드 프로세스 간소화
- Maven을 사용한다고 해서 기본 메커니즘에 대한 지식이 필요없다는 것은 아니지만, Maven은 많은 세부 사항을 알 필요가 없다.
- 일관된 빌드 시스템 제공
- 표준화된 빌드 절차를 통해 다양한 프로젝트를 동일한 방식으로 빌드할 수 있게 한다.(프로젝트 객체 모들 POM과 일련의 플러그인을 사용하여 프로젝트를 빌드한다.)
- 하나의 Maven 프로젝트를 익히면 다른 Maven 프로젝트도 쉽게 이해할 수 있다.
- 품질 높은 프로젝트 정보 제공
- POM에서 가져온 정보와 프로젝트 소스에서 생성된 일부 유용한 프로젝트 정보를 제공한다.
- 소스 컨트롤러에서 직접 생성된 변경 로그
- 교차 참조된 소스
- 프로젝트가 관리하는 메일링 리스트
- 프로젝트가 사용하는 종속성
- 커버리지를 포함한 단위 테스트 보고서
- POM에서 가져온 정보와 프로젝트 소스에서 생성된 일부 유용한 프로젝트 정보를 제공한다.
- 모범 사례 개발 권장
- 현재의 최선 개발 관행 원칙을 모아 프로젝트가 그 방향으로 쉽게 안내되도록 하는 것을 목표로 한다.
- 릴리스 및 이슈 관리와 같은 프로젝트 워크플로우에도 도움을 준다.
- 프로젝트의 디렉토리 구조를 배치하는 방법에 대한 지침을 제안한다.
- 프로젝트에 재구성할 수 없는 특이 빌드 구조가 있는 경우, 일부 기능이나 Maven 사용 자체를 포기해야 할 수도 있다.
Maven에 대한 오해
- Maven은 사이트 및 문서화 도구이다.
- Maven은 Ant를 확장하여 종속성을 다운로드할 수 있게 한다.
- Maven은 재사용 가능한 Ant 스크립트 모임이다.
Maven은 이러한 기능을 수행하지만 이것이 Maven의 유일한 기능은 아니며, Maven의 목표는 상당히 다르다.
Maven의 Lifecycle
단계 | 내용 |
Default(Build) | 일반적인 빌드 프로세스를 위한 모델이다. |
Clean | 빌드 시 생성되었던 파일들을 삭제하는 단계 |
Validate | 프로젝트가 올바른지 확인하고 필요한 모든 정보를 사용할 수 있는지 확인하는 단계 |
Compile | 프로젝트의 소스코드를 컴파일 하는 단계 |
Test | 유닛(단위) 테스트를 수행 하는 단계(테스트 실패시 빌드 실패로 처리, 스킵 가능) |
Pacakge | 실제 컴파일된 소스 코드와 리소스들을 jar, war 등등의 파일 등의 배포를 위한 패키지로 만드는 단계 |
Verify | 통합 테스트 결과에 대한 검사를 실행하여 품질 기준을 충족하는지 확인하는 단계 |
Install | 패키지를 로컬 저장소에 설치하는 단계 |
Site | 프로젝트 문서와 사이트 작성, 생성하는 단계 |
Deploy | 만들어진 package를 원격 저장소에 release 하는 단계 |
Gradle
Gradle은 CI/CD를 위해 아래 작업들을 자동화 시켜 주는 Groovy 기반의 오픈소스 빌드 도구이다.
- Compile - Java 파일의 소스 코드를 컴퓨터가 이해할 수 있도록 바이트 코드로 변환
- Test - 유닛 테스트, UI 테스트
- Packaging - 스프링 코드를 패키징 해 .jar 파일이나 .war 파일로 생성
- Deploy & Run - 서버 실행
가장 최근에 나온 자바 빌드 도구로 Groovy 문법을 사용한다.
build.gradle에 스크립트를 작성하며, 대규모 프로젝트에서 복잡해지는 경향이 있는 XML 기반 스크립트에 비해 관리가 편하다는 장점을 갖는다.
핵심 개념
프로젝트
- Gradle 프로젝트 : 애플리케이션이나 라이브러리와 같이 빌드할 수 있는 소프트웨어 조각
- 단일 프로젝트 빌드 : 루트 프로젝트라는 단일 프로젝트를 포함한다.
- 다중 프로젝트 빌드 : 하나의 루트 프로젝트와 여러 서브 프로젝트를 포함한다.
빌드 스크립트
- 프로젝트를 빌드하기 위해 Gradle이 수행해야 할 단계를 자세히 기술
- 각 프로젝트는 하나 이상의 빌드 스크립트를 포함할 수 있다.
종속성 관리
- 프로젝트에 필요한 외부 리소스를 선언하고 해결하는 자동화 기술
- 각 프로젝트는 일반적으로 Gradle이 빌드 중에 해결할 여러 외부 종속성을 포함한다.
작업
- 코드 컴파일이나 테스트 실행과 같은 기본 작업 단위
- 각 프로젝트는 빌드 스크립트나 플러그인 내에서 정의된 하나 이상의 작업을 포함한다.
플러그인
- Gradle의 기능을 확장하고 선택적으로 프로젝트에 작업을 추가하는 데 사용한다.
Gradle 프로젝트 구조
프로젝트의 루트 디렉터리에 gradlew 및 gradlew.bat 파일이 있으면 Gradle이 사용된다는 명확한 표시이다.
Gradle 프로젝트는 다음과 비슷하게 보일 것이다.
project
├── gradle
│ ├── libs.versions.toml
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle(.kts)
├── subproject-a
│ ├── build.gradle(.kts)
│ └── src
└── subproject-b
├── build.gradle(.kts)
└── src
- gradle 디렉토리: 래퍼 파일 등을 저장한다.
- 종속성 관리를 위한 Gradle 버전 카탈로그: libs.versions.toml
- Gradle 래퍼 스크립트: gradlew 및 gradlew.bat
- Gradle 설정 파일: 루트 프로젝트 이름 및 서브프로젝트를 정의한다. - settings.gradle(.kts)
- 서브프로젝트의 Gradle 빌드 스크립트: subproject-a와 subproject-b의 build.gradle(.kts)
- 프로젝트의 소스 코드 및 기타 파일 : src
Gradle의 Lifecycle
단계 | 내용 |
초기화(initialization) | 빌드 대상 프로젝트를 결정하고 각각에 대한 Project객체를 생성한다. settings.gradle 파일에서 프로젝트 구성한다. |
구성(Configuration) | 빌드 대상이 되는 모든 프로젝트의 빌드 스크립트를 실행한다. |
실행(Execution) | 구성 단계에서 생성하고 설정된 프로젝트의 태스크 중에 실행 대상을 결정한다. gradle 명령행에서 지정한 태스크 이름 인자와 현재 디렉토리를 기반으로 태스크를 결정하여 선택된 태스크들을 실행한다. |
build.gradle 파일
api - 내부 의존성을 컴파일과 런타임 모두에 보이는 API 의존성
implementation - 내부 의존성을 런타임에서만 보이는 구현 의존성
compileOnly - 컴파일에만 사용되는 의존성 정의
runtimeOnly - 런타임에만 사용되는 의존성 정의
test + implementation, compileOnly, runtimeOnly - 해당 의존성을 테스트 시에만 사용하도록 정의
Gradle vs Maven
유연성
- Gradle
- Google은 Gradle을 Android 공식 빌드 도구로 선택했다. 이는 빌드 스크립트가 코드로 작성되기 때문이 아니라, Gradle이 근본적으로 확장 가능하도록 설계되었기 떄문이다.
- Gradle의 모델은 C/C++을 사용한 네이티브 개발에도 사용될 수 있으며, 어떤 생태계든 확장할 수 있다. 예를 들어, Gradle은 Tooling API를 사용하여 임베딩을 염두에 두고 설계되었다.
- Maven
- Gradle과 Maven 모두 설정보다 관습을 중시하지만, Maven은 매우 엄격한 모델을 제공하여 사용자 정의가 번거롭고 때로는 불가능하다. 이는 특별한 요구 사항이 없는 경우 Maven 빌드를 이해하기 쉽게 만들지만, 많은 자동화 문제에 적합하지 않다.
- 반면 Gradle은 권한과 책임을 가진 사용자를 염두에 두고 설계되었다.
성능
빌드 시간을 단축하면 소프트웨어를 더 빨리 배포할 수 있다. Gradle과 Maven은 모두 병렬 프로젝트 빌드 및 병렬 종속성 해결 방식을 사용한다. 가장 큰 차이점은 Gradle의 작업 회피 및 점증성 메커니즘이다.
Gradle이 Maven보다 빠른 이유는 다음과 같은 주요 기능들 덕분이다.
- 점증성 : Gradle은 작업의 입력 및 출력을 추적하여 필요한 작업만 수행하고, 가능한 경우 변경된 파일만 처리한다.
- 빌드 캐시 : 동일한 입력을 가진 다른 Gradle 빌드의 빌드 출력을 재사용하여, 기기 간에도 빌드 출력을 재사용할 수 있다.
- Gradle Document : 빌드 정보를 메모리에서 "핫" 상태로 유지하는 장기 실행 프로세스
이와 같은 성능 기능들로 인해, 거의 모든 시나리오에서 Gradle이 Maven보다 두 배 이상 빠르며, 빌드 캐시를 사용하는 대형 빌드에서는 최대 100배 빠르다.
사용자 경험
- IDE 지원: Maven의 오래된 역사를 통해 많은 사용자에게 더 나은 IDE 지원을 제공한다. 그러나 Gradle의 IDE 지원도 빠르게 개선되고 있다.
- 명령줄 인터페이스(CLI): 많은 사용자가 명령줄 인터페이스를 통해 빌드 작업을 실행하는 것을 선호한다. Gradle은 gradle tasks와 같은 탐색 기능, 개선된 로깅, 명령줄 완성 기능을 갖춘 현대적인 CLI를 제공한다.
- Build Scan™: Gradle은 빌드를 디버그하고 최적화하는 데 도움을 주는 인터랙티브 웹 기반 UI를 제공한다. 이를 통해 조직은 빌드 이력을 수집하고, 트렌드 분석을 수행하며, 디버깅을 위해 빌드를 비교하거나 빌드 시간을 최적화할 수 있다.
종속성 관리
- 기본 제공 종속성 해결 기능: 두 빌드 시스템 모두 구성 가능한 리포지토리에서 종속성을 해결하는 기능을 내장하고 있습니다. 두 시스템 모두 로컬 캐싱 및 병렬 다운로드를 지원한다.
- Gradle: 종속성 선택 및 대체 규칙을 사용자 정의할 수 있으며, 프로젝트 전체에서 불필요한 종속성을 처리할 수 있다. 이는 여러 소스 프로젝트를 함께 빌드하여 복합 빌드를 생성할 수 있게 한다. Gradle은 사용자 정의 종속성 스코프를 지원하여 더 잘 모델링되고 빠른 빌드를 제공한다. Gradle은 전체 충돌 해결을 수행하여 그래프에서 가장 높은 버전의 종속성을 선택한다.
- Maven: 기본 종속성 스코프가 적어 일반적인 시나리오에서 모듈 아키텍처가 어색해질 수 있다. 예를 들어, 단위 테스트와 통합 테스트 간의 분리가 없다. Maven은 종속성 충돌 해결에서 선언 순서에 영향을 받는 최단 경로 방식을 사용한다.
라이브러리 생산자 및 소비자
- Gradle: 라이브러리 생산자는 api와 implementation 종속성을 선언하여 소비자의 클래스 경로에 불필요한 라이브러리가 누출되지 않도록 할 수 있습니다. Gradle은 기능 변형 및 선택적 종속성을 완전히 지원한다.
- Maven: 발행자는 선택적 종속성을 통해 메타데이터를 제공할 수 있지만, 이는 문서로만 제공된다.
이 비교를 통해 Gradle과 Maven의 주요 차이점과 각 도구의 강점을 이해할 수 있다. Gradle은 더 유연하고 성능이 뛰어나며 사용자 경험이 좋고 종속성 관리를 더 잘 지원하는 반면, Maven은 더 오래되고 안정적인 도구로 다양한 환경에서 널리 사용되고 있다.
참조
https://docs.gradle.org/current/userguide/gradle_basics.html#gradle
https://gradle.org/maven-vs-gradle/
https://galid1.tistory.com/194
https://velog.io/@alicesykim95/Maven%EA%B3%BC-Gradle%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90
잡담
늦게 나온만큼 Maven과 Ant의 장점들을 모아서 만들어졌기 때문에 Gradle이 편리하고 빠르다고 한다.
Maven이랑 Gradle 비교하는 쪽은 Gradle 사이트에서 가져왔는데 그만큼 자신있어서 비교해놓은 것 같다.
'Spring' 카테고리의 다른 글
[Spring] JDBC (0) | 2024.07.09 |
---|---|
[Spring] Spring vs Spring Boot (0) | 2024.07.09 |
[Spring] Exception Handling (0) | 2024.07.05 |
Validation in Spring Boot (0) | 2024.07.02 |
Validating Form Input (0) | 2024.07.02 |