[Environment] Maven vs Gradle
Maven이란?
- Apache Ant의 대안으로 만들어진 프로젝트 관리 도구이다.
- 전체적인 라이프 사이클을 관리하는 도구이며 프로젝트의 의존성 관리, 라이브러리 관리 등을 제공한다.
- 필요한 라이브러리를 pom.xml에 정의해 놓으면 지정한 라이브러리와 해당 라이브러리가 동작하는 데 필요한 다른 라이브러리들까지 네트워크를 통해서 자동으로 다운 받아준다.
기존에는 Ant가 많이 사용되었고 이후 Maven이, 현재는 Gradle이 많이 쓰인다고 한다.
LifeCycle
- Maven에서는 clean, build, suite 세 가지 Lifecycle을 제공한다.
- compile, test, package, depooy 등의 과정은 빌드 Lifecycle에 속한다.
- 각 LifeCycle은 순서를 갖는 단계(phase)로 구성된다.
- Maven의 LifeCycle을 이해하려면 Phase와 Goal의 개념을 이해해야 한다.
- Build: 일반적인 빌드 프로세스를 위한 모델
- Clean: 빌드 시 생성되었던 파일들을 모두 제거
- Validate: 프로젝트가 올바른지 확인하고 필요한 모든 정보를 사용할 수 있는지 확인
- Compile: 소스코드를 컴파일
- Test: jUnit과 같은 테스트 코드를 실행, 테스트가 실패하면 빌드를 멈춤
- Package: compile, test-compile, test순으로 실행 한 후 jar, war 파일 등의 배포를 위한 패키지로 만듬
- Verify: 통합 테스트 결과에 대한 검사를 실행하여 품질 기준을 충족하는지 확인
- Install: 로컬 저장소에 패키지 배포
- Site: 프로젝트 문서 생성
- Deploy: package를 원격 저장소에 release
1) Phase
- Build LifeCycle 각각의 단계를 의미한다.
- Phase 간에 의존 관계가 있어서 각 Phase가 실행되려면 이전 단계의 Phase가 선행되어야 한다.
2) Goal
- 최소한의 실행 단위이다.
- Maven에서는 하나의 플러그인에서 여러 작업을 수행할 수 있도록 지원하며 플러그인에서 실행할 수 있는 각각의 기능을 goal이라고 한다.
POM
- pom.xml파일을 지칭하며 메이븐을 이용하는 프로젝트의 root에 존재한다. 프로젝트 생성 시 빌드 툴을 maven으로 설정하면 최상위 디렉토리에 자동으로 pom.xml파일이 생성된다.
- 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my</groupId>
<artifactId>www</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>www Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<org.aspectj-version>1.8.3</org.aspectj-version>
<java-version>1.8</java-version>
<org.springframework-version>4.0.1.RELEASE</org.springframework-version>
<log4jVersion>2.10.0</log4jVersion>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<repositories>
<repository>
<id>mesir-repo</id>
<url>https://maven.atlassian.com/3rdparty/</url>
</repository>
<repository>
<id>Spring Plugins</id>
<url>http://repo.spring.io/plugins-release</url>
</repository>
</repositories>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
- name: 프로젝트 이름
- dependency: 라이브러리
- build: 빌드에 사용할 플러그인 목록
Gradle이란?
- 유연한 범용 빌드 자동화 시스템이다.
- 안드로이드 앱을 만드는 데 필요한 안드로이드 스튜디오의 공식 빌드 시스템이기도 하며 Java, C/C++, Python 등과 같은 여러 언어를 지원한다.
- Maven과 같은 구조화 된 프레임워크를 가지고 pom.xml파일과 ivy.xml 파일에 대한 migration 편이성을 제공한다.
- xml이 아닌 Groovy 기반의 DSL을 사용한다.
장점
- Groovy를 사용하여 코드로서 설정 정보를 구성하기 때문에 xml보다 구조적 장점을 가진다.
- 모든 프로젝트가 일관된 디렉터리 구조를 가지고 빌드 프로세스를 유지하도록 도와준다.
- 의존성 관리의 다양한 방법을 제공한다.
- 멀티 프로젝트 빌드를 지원한다.
plugins {
id 'org.springframework.boot' version '2.5.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'war'
}
group = 'kr.co'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation group: 'com.google.code.gson', name: 'gson'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'
runtimeOnly 'mysql:mysql-connector-java'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
//Thymeleaf
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
//JPA
implementation group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: '7.0.57'
implementation group: 'org.springframework', name: 'spring-orm', version: '5.3.3'
// querydsl 사용
implementation 'com.querydsl:querydsl-jpa'
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.7.1'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
//email sender
implementation 'com.sun.mail:javax.mail:1.6.2'
//ftp
implementation 'org.springframework.integration:spring-integration-sftp:5.1.8.RELEASE'
implementation 'org.springframework.integration:spring-integration-ftp:5.1.8.RELEASE'
}
test {
useJUnitPlatform()
}
- plugin: 미리 구성해 놓은 task들의 그룹
- implementation: 프로젝트 컴파일 과정에서 필요한 라이브러리
- providedRuntime: runtime시에만 필요하고 실행환경에서 제공되는 dependency를 설정
- testImplementation: test 시에 필요한 dependency
개인 견해
Maven과 Gradle을 모두 사용해 보았다.
처음에는 Maven이 익숙해서 약간의 어색함이 있었지만..결론은 편하다.Maven보다
xml 은 아무래도 가독성이 떨어지는 점도 있고 상속 구조를 가진다는 것 또한 의존 관계가 복잡할 때는 단점으로 나타난다.
Gradle 자체가 Maven의 편리한 기능을 가지고 있기 때문에 Gradle을 사용하지 않을 이유가 없다.
그리고 이거는 몸소 체감하지는 못했다만..
Gradle이 Maven보다 훨씬 빠르다고 한다. 빌드타임 비용을 생각한다면 이것도 크리티컬한 장점이 아닐까 싶다.
#References
1] http://wiki.gurubee.net/display/SWDEV/Maven+Lifecycle
2] https://willbesoon.tistory.com/93