영권's
2021-08-16 TIL (Build) 본문
Spring 프로젝트를 만들기 위한 빌드툴
- Maven
- Gradle
Build 란?
- 필요한 라이브러리를 다운받고 classpath에 추가합니다.
- 소스 코드를 컴파일합니다.
- 테스트를 실행합니다.
- 컴파일된 코드를 packaging 합니다. -> jar / war / zip etc
- packaging 된 파일을 주로 artifacts라고 부르고 서버나 레포지토리에 배포합니다.
- 구동이 되는 서비스를 패키징 했을 경우 서버에 배포하지만 Third party library 형태로 외부에게 라이브러리 형태로 제공하기 위해서 배포할 때는 레포지토리에 배포할 수 있다.
이런 일(task)들을 자동화 하게 해주고 "이런 일들을 하겠다."라고 기술할 수 있게 하는데 이렇게 기술한 파일을 build script라고 부른다.
Maven
빌드 도구로 주로 자바기반의 프로젝트에서 많이 사용됩니다.
xml기반으로 설정 모델을 제공하고 pom.xml 파일로 작성할 수 있습니다.
POM은 project object model의 약어입니다.
그래서 pom.xml를 보면 프로젝트 구조를 파악 할 수 있다.
Maven's Objective
Maven 홈페이지에 보시면 Maven 이 이루고자 하는 목표를 확인할 수 있습니다.
Maven을 사용하는 이유
- Maven은 archetypes 라는 프로젝트 템플릿을 제공해서 매번 같은 설정을 반복하지 않아도 됩니다.
- 프로젝트에서 사용하는 외부 라이브러리인 dependency를 관리해줍니다.
- 다운로드도 해주고 최신버젼으로 업데이트되 쉽게 할 수 있습니다. 그리고 라이브러리들의 호환성도 관리해줍니다.
- 플러그인과 외부 라이브러리를 분리하여 관리합니다.
- 플러그인에서 사용하는 라이브러리가 프로젝트의 dependency 와 섞이지 않게 도와줍니다. 물론 각각의 Repository가 별도로 존재합니다.
- dependency를 다운받는 Repository가 로컬이 될 수도 있고 Maven Central과 같이 공개된 Repository가 될 수도 있습니다.
- 비공개 Repository에서 다운 받을 수 도 있습니다.
- Nexus를 이용하면 손 쉽게 비공개 Repository를 만들 수 있습니다.
archetypes를 이용해서 프로젝트 만들기
- 생성 후 빌드가 다 끝나면 pom.xml에 정의가 된다.
- 웹 문서가 html로 작성하면 브라우저가 dom을 만드는 것처럼 pom.xml를 작성하면 maven이 project object model이라는 객체를 만드는 것입니다.
- 그리고 pom에 의해서 프로젝트에 의해서 dependency가 다운받아지고 라이프 사이클이 실행되고 프로젝트가 구성되는 것이다.
프로젝트 생성 시 Coordinates라고 해서 작성한 부분이 있는데 이 부분은 세상의 수많은 maven 프로젝트들을 식별하는데 사용된다.
Maven coordinates 구성
- groupId는 대부분 회사나 단체를 작성 ex) org.springframework
- artifactId는 프로젝트 모듈에 대한 이름 ex)spring-context
- version은 말 그대로 프로젝트 버전을 나타내는데 SNAPSHOT은 계속 개발이 되는 과정을 뜻하고 RELEASE를 적으면 배포할 버전을 뜻할 수 있다. ex) 5.2.15.RELEASE
Maven 은 Multiple Module을 지원합니다. 즉, 하나의 프로젝트에 여러 프로젝트를 관리할 수 있습니다.
<modules>
<module>service-a</module>
<module>service-b</module>
</modules>
대체로 이러한 구조를 모노레포, 멀티 모듈, 멀티레파지토리 등으로 부르는데 하나의 폴더에 여러 프로젝트를 관리하는 형태입니다.
마이크로서비스 환경에서 컴파일타임의 의존관계를 편리하게 가져가기 위해서 자주 사용됩니다.
(https://www.baeldung.com/maven-multi-module 참고해주세요)
- 이렇게 생성 했을 때 하나의 상위 모듈 아래에 두개의 모듈이 만들어지고 각 모듈마다 pom파일을 가지고 있다.
- 위의 모듈들은 org.programmers라는 그룹 안에 있는 service-a, service-b 모듈이다.
- dependency 안에 있는 다른 메이븐 모듈 혹은 라이브러리과 의존관계를 작성할 수 있다.
- 그러면 해당 프로젝트를 돌리기 위해서는 dependency에 작성된 라이브러리들이 필요하다는 것을 알려준다.
- 여기서는 junit 프레임워크와 의존관계가 만들어졌고 test를 할 때 사용하겠다 라는 것을 볼 수 있다.
- Maven은 프로젝트는 미리 정의된 Build Life Cycle이 존재한다.
- build lifecycle은 프로젝트를 빌드하고 배포하고는 일렬의 절차를 의미합니다.
- 미리 정의된 라이프사이클은 default, clean 그리고 site 가 존재하는데 이 default가 아래와 같은 단계로 구성됩니다.
default 라이프사이클은 프로젝트 배포를 위한 처리하고, clean 라이프사이클은 프로젝트 정리를 처리하고 site 라이프사이클은 프로젝트의 사이트 문서 작성을 합니다.
- validate - 프로젝트가 올바르고 필요한 모든 정보를 사용할 수 있는지 확인합니다.
- compile - 프로젝트의 소스 코드 컴파일.
- test - 적절한 장치 테스트 프레임워크를 사용하여 컴파일된 소스 코드를 테스트합니다. 이러한 테스트에서는 코드를 패키지화하거나 배포할 필요가 없습니다.
- package - 컴파일된 코드를 가져와 JAR과 같은 배포 가능한 형식으로 패키징합니다.
- verify(확인) - 통합 테스트 결과에 대한 모든 검사를 실행하여 품질 기준이 충족되는지 확인합니다.
- install - 패키지를 로컬 저장소에 설치하여 로컬에서 다른 프로젝트의 종속성으로 사용합니다.
- deploy(배포) - 빌드 환경에서 완료되어 최종 패키지를 원격 저장소로 복사하여 다른 개발자 및 프로젝트와 공유합니다.
- clean - 프로젝트를 정리한다. (build해서 target에 만들어진 파일들을 삭제)
다음과 같이 인텔리제이에서도 Maven 프로젝트의 LifeCycle, Plugins, Dependencies를 확인할 수 있습니다.
- test, package를 실행하면 테스트 후 target 안에 파일들이 만들어진다.
- install 하면 로컬 레포지토리에 jar가 copy가 되고 deploy를 실행하면 public 레포나 private 레포에 배포가 가능해진다.
다음과 같이 터미널을 사용해서도 maven 명령을 사용할 수 있다.
(윈도우에서 인텔리제이와 git bash 연동해서 사용하기 / 공식 가이드 링크)
Transitive Dependencies
Transitive 의존성이란, 의존성의 의존성을 이야기합니다.
만약 a가 b를 참조하고, b가 c를 참조한다면, "a는 c를 transitive 의존성" 으로 간주합니다.
만약 c가 d를 참조한다면, a는 d에 대해서도 transitive 의존성을 갖습니다.
이러한 경우, maven은 의존성 트리를 구성하여 동일한 groupId, artifactId에 대해서는
가장 최신의 version 정보를 사용하게 됩니다.
이러한 기능은 때로는 좋아 보이지만, 때로는 버전 간 충돌, 라이브러리 간 충돌 등의 문제를 야기할 수 있습니다.
출처 : https://m.blog.naver.com/PostView.naver?blogId=naverdev&logNo=120113627296&proxyReferer=https:%2F%2Fwww.google.com%2F
mvn dependency:tree 명령어를 이용해서 의존 관계를 트리 형태로 볼 수 있습니다.
만약 구조가 위에 첫번째 트리처럼 되어 있다면 D는 어떤 버전을 사용할까?
- 공식 문서에는 가장 가까운 정의를 사용한다(Maven picks the "nearest definition". )이렇게 나와있다.
- 종속성은 A->B->C->D 2.0 과 A->E->D1.0 중 후자인 1.0버전을 의존받게 되는 것이다.
- 만약 무조건 D 2.0 버전을 의존하게 하려면 두번째 트리처럼 A 밑에 바로 계층구조를 형성하면 된다.
- 이를 통해서 dev-kdt 모듈이 junit을 사용하고 또 hamcrest 라는 것을 사용한다 를 알 수 있다.
- 또 마지막에 적힌 값(ex)test)이 dependency scope이다.
- 아무것도 적지 않으면 컴파일이다.
- compile
이 범위는 기본 Scope 이고, 지정된 Scope가 없는 경우 사용됩니다. 컴파일 종속성은 프로젝트의 모든 클래스 경로에서 사용할 수 있습니다. 또한 이러한 종속성은 종속 프로젝트에 전파됩니다. - provided
이는 컴파일과 비슷하지만 런타임에 JDK 또는 컨테이너가 종속성을 제공하기를 기대함을 나타냅니다. 예를 들어, Java Enterprise Edition용 웹 응용 프로그램을 작성할 때 웹 컨테이너가 이러한 클래스를 제공하므로 서블릿 API 및 관련 Java EE API에 대한 종속성을 제공된 범위로 설정합니다. 이 범위의 종속성은 컴파일 및 테스트에 사용되는 클래스 경로에 추가되지만 런타임 클래스 경로는 추가되지 않습니다. 그것은 일시적인 것이 아니다. - runtime
이 범위는 종속성이 컴파일에 필요하지 않고 실행에 필요함을 나타냅니다. Maven은 런타임 및 테스트 ClassPath에 이 범위의 종속성을 포함하지만 컴파일 ClassPath는 포함하지 않습니다. - test
- 이 범위는 종속성이 응용 프로그램의 정상적인 사용에 필요하지 않으며 테스트 컴파일 및 실행 단계에만 사용할 수 있음을 나타냅니다.
- 이 scope은 transitive 되지 않습니다.
- 일반적으로 이 범위는 JUnit 및 Mockito와 같은 테스트 라이브러리에 사용됩니다. 또한 이러한 라이브러리가 장치 테스트(src/test/java)에는 사용되지만 모델 코드(src/main/java)에는 사용되지 않는 Apache Commons IO와 같은 비테스트 라이브러리에도 사용됩니다.
- system
이 범위는 JAR이 명시적으로 포함된 JAR을 제공해야 한다는 점을 제외하고 provide scope와 유사합니다. - import
이 범위는 <dependencyManagement> 섹션의 pom 유형에 종속된 경우에만 지원됩니다.
이것은 종속성이 지정된 POM의 <의존성 관리> 섹션에 있는 유효 종속성 목록으로 대체됨을 나타냅니다.
Gradle
- Gradle은 또 다른 Build Tool로 Groovy 기반으로 빌드 스크립트를 작성하게 도와줍니다.
- 최근에는 코틀린도 지원해서 코틀린 기반으로 Build Script를 작성할 수 있습니다.
- 이렇게 두 언어로 DSL(Domain Specific Language)을 제공해서 Build 영역의 문제를 해결하기 위한 스크립트 언어를 만든것입니다. XML보다 더 간결하게 빌드 스크립트를 작성할 수 있습니다.
- 반대로 그 언어를 배워야하기도 합니다.
기본적으로 Artifact Coordinates는 Maven Coordinates와 같은 개념입니다.
프로젝트가 생성되면 build.gralde를 확인할 수 있습니다.
Project 와 Task
- Gradle Build는 하나 이상의 프로젝트를 지원합니다.
- Maven의 Multiple Module과 비슷하다고 보면 됩니다.
- 하나의 프로젝트는 하나 이상의 Task로 구성됩니다. Task는 말 그대로 클래스를 컴파일하거나 Jar를 생성하거나 하는 build를 위해 하는 작업이라고 보면 됩니다.
- 일반적으로 Task는 Plugin에 의해서 제공됩니다. 물론 직접 Task를 만들수도 있지만 대체로 Plugin에서 제공하는 Task를 사용합니다.
Plugin
- Gradle에 실제 Task와 주요한 기능들을 추가하게 하는건 바로 Plugin들입니다. 하나의 프로젝트에 여러 플러그인을 추가할 수 있습니다.
- 이렇게 Plugin을 추가하게되면 새로운 Task들이 추가되고 도메인 객체나 특정 컨벤션들이 추가됩니다.
- 예를 들어 Java Plugin을 추가하게되면 JavaCompile 테스크도 추가되고 src/main/java와 같은 컨벤션도 추가됩니다.
내가 자세히 살펴 봐야 될 것.
Plugin에 대한 자세한 내용은 Using Gradle Plugins 문서에서 자세히 설명되어 있습니다.
application plugin에 대해서는 https://docs.gradle.org/current/userguide/application_plugin.html 에서 자세히 살펴보세요. 그리고 기본적으로 Java와 JVM 프로젝트들에 대한 내용은 https://docs.gradle.org/current/userguide/building_java_projects.html 문서에서 확인할 수 있습니다.
Maven과 Gradle 비교
- https://gradle.org/maven-vs-gradle/
- https://mindmajix.com/gradle-tutorial
- https://www.jrebel.com/blog/java-build-tools-comparison
참고자료
'데브코스 웹 백엔드 > TIL' 카테고리의 다른 글
TIL 09-16 클론 코딩 및 과제 피드백 수정 (0) | 2021.09.17 |
---|---|
20210817 TIL - Spring (의존성) (2) | 2021.08.18 |
2021-08-13 TIL (데이터베이스 - 트랜잭션,VIEW) (0) | 2021.08.14 |
TIL - (데이터베이스) (0) | 2021.08.12 |
20210809 - TIL (데이터베이스) (0) | 2021.08.10 |