Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

개발하지연

[maven] maven이란? (개념, 라이프사이클, 결과물) 본문

개발환경

[maven] maven이란? (개념, 라이프사이클, 결과물)

JeongJiyeon 2024. 1. 6. 21:24

maven을 사용하기도 하고, 여러 글도 읽어봤지만 아직 감이 잘 안와서 필요한 부분들 정리해보려고 작성하는 글!

 

maven이란?

[개발 - 빌드 - 배포] 단계에서 프로젝트를 빌드해주는 도구!

https://maven.apache.org/what-is-maven.html

  1.  

💡 빌드란?

소스 코드 → 실행파일(jar)로 변환하는 작업.
컴파일과 개념이 헷갈릴 수 있는데, 빌드 과정 안에 컴파일 단계가 포함되어 있다.

 

빌드과정을 명령어로 보면 아래와 같다.

# 소스 코드 컴파일
$ javac Hello.java

# 패키징 (jar 이름, main class, 컴파일 대상 파일 정의)
$ jar --create --file Hello.jar --main-class Hello -C java/main/ .

# 실행 (deploy)
$ java -jar Hello.jar

 

  1. 컴파일 (compile) : 소스코드 → 바이너리 파일로 변환
    • 소스코드 컴파일해서 바이너리 파일(.class)로 변경
  2. 패키징 : 바이너리 파일이 참조하는 라이브러리들을 연결해주고, 실행파일로 패키징
    • java의 경우 JVM에서 실행가능한 jar로 패키징한다.
    • linking이라고도 하는듯

maven 장점

  • 빌드 프로세스를 간편하게 해준다
  • 프로젝트 라이브러리 관리가 쉬워진다
    (pom.xml에 라이브러리를 리스팅해놓으면 참조된 라이브러리까지 다 찾아서 추가해준다)

maven 라이프사이클

intellij maven plugin

 

라이프사이클이란, 메이븐이 정의하고 있는 빌드 순서이다.

라이프사이클을 구성하는 단계는 phase라고 하고, phase는 goal(가장 작은 태스크)을 실행한다

라이프사이클과 페이즈는 모두 개념이고, 실제 실행되는 작업은 goal에 정의되어있다.
각 페이즈에서 실행하는 plugin:goal 정보 참고 -> 공식문서   

 

💡 maven goal, plugin

  • goal은 maven에서 가장 작은 태스크 하나를 정의한다
  • plugin은 maven 아티팩트로, 여러개의 goal이 하나의 plugin에 정의되어있다
  • maven 내장된 전체 플러그인 정보 → 공식문서

 

아래는 각 라이프사이클에 대한 설명이다. ->  공식문서 참고

아래 문서에서 정의된 라이프사이클은 clean (빌드 결과물 정리) / default (빌드) / site (문서 생성) 세가지인데 각 라이프사이클 내 phase에서만 순서에 의존적이다. (= 특정 단계가 실패하면 다음 단계로 넘어가지 않는다)

 

Maven – Introduction to the Build Lifecycle

The build lifecycle is simple enough to use, but when you are constructing a Maven build for a project, how do you go about assigning tasks to each of those build phases? The first, and most common way, is to set the packaging for your project via the equa

maven.apache.org

 

 

보편적으로는 아래 7가지 라이프사이클로 정의되어서 사용되는 듯하고, intellij maven 플러그인에도 다음과 같이 정의되어있다!

 

1. clean : 빌드과정에서 생성된 파일들을 모두 삭제하는 단계

해당 라이프사이클에서 실행하는 phase는 아래와 같다.

maven clean 실행 시 실행되는 코드는 maven-clean-plugin 에 정의되어있고, 한 번 슬쩍 찾아본김에 첨부. ->  git code

 

2. validate : 프로젝트가 필요한 모든 정보를 사용할 수 있는지 검증하는 단계

해당 라이프사이클에서 실행하는 phase는 아래와 같다.

 

 

3. compile : 소스코드를 컴파일 하는 단계

해당 라이프사이클에서 실행하는 phase는 아래와 같다.

소스코드를 컴파일, 리소스 복사해서 target/clasees에 생성한다.

 

 

4. test : 테스트코드가 컴파일되고 테스트를 수행하는 단계
해당 라이프사이클에서 실행하는 phase는 아래와 같다.

테스트 코드를 target/test-classes에 복사하고, 테스트를 수행한다

*mavn 빌드 시 특정 단계가 실패하면 이후 단계가 실행되지 않기 때문에 -Dmaven.test.skip=true 사용하여 테스트는 패스하기도 한다.

 

 

5. pacakge : 배포를 위한 패키지(jar, war,,)를 만드는 단계
해당 라이프사이클에서 실행하는 phase는 아래와 같다.

컴파일된 소스코드와 리소스, 의존성 라이브러리들을 같이 패키징하여 실행파일로 만든다.

pom.xml에 어떤 파일로 패키징할지 정의하면 그에 맞게 패키징된다.

    <packaging>jar</packaging>

 

 

6. verify : 통합 테스트 결과에 대한 검사를 실행하는 단계

해당 라이프사이클에서 실행하는 phase는 아래와 같다.

 

7. site : 현재 프로젝트에 대한 문서와 사이트를 생성하는 단계

해당 라이프사이클에서 실행하는 phase는 아래와 같다.

 

 

8. install : 생성한 패키지를 로컬 저장소에 추가하는 단계

해당 라이프사이클에서 실행하는 phase는 아래와 같다.

  • .m2/repository 에 추가

 

9. deploy : 패키지를 원격 저장소에 추가하는 단계

해당 라이프사이클에서 실행하는 phase는 아래와 같다.


 

라이프사이클 결과물 까보기 (clean → compile → test → package)

1. clean - target 디렉토리 삭제
빌드 라이프사이클을 진행하면 target 디렉토리에 각 단계의 결과물이 생성되는데, 해당 디렉토리를 clear한다.

 

2. compile - src/main/java 아래의 코드들을 컴파일 후 target/classes에 클래스파일이 생성된다.

  • target/classes : 소스코드가 복사되는 디렉토리.
  • target/maven-status : 각 phase에서 필요한 빌드 상태나 정보를 저장해두는 디렉토리
  • target/generated-sources : 코드 생성 라이브러리 혹은 annotation 프로세서에 의해 컴파일 타임에 생성되는 코드가 위치하는 디렉토리
    (진행하는 프로젝트에서 아래와 같이 pom.xml의 generate-sources에 mapstruct Annotation Processor 작업을 정의해놨는데, 해당 디렉토리에 @Mapper 어노테이션으로 정의한 클래스의 구현체가 생성됐다. lombok이나 buidler도 동일하게 해당 디렉토리에 구현체가 생성되는 듯 하다.)
<plugin>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-maven-plugin</artifactId>
    ...
    <execution>
        <id>kapt</id>
        <phase>generate-sources</phase>
        <goals>
            <goal>kapt</goal>
        </goals>
        <configuration>
            <annotationProcessorPath>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${mapstruct.version}</version>
            </annotationProcessorPath>
            ...
        </configuration>
    </excution>
</plugin>

 

 

3. test - src/test 아래의 코드들을 컴파일 후 target/test-classes에 테스트코드가 생성되고 실행된다.

  • target/generated-test-sources : 위와 동일하게 컴파일 타임에 생성되는 코드가 위치하는 디렉토리
  • target/test-classes : 테스트 코드가 복사되는 디렉토리
  • target/surefire-reports : 테스트 결과가 생성되는 디렉토리

 

4. package - target 디렉토리 하위에 최종적으로 패키징된 jar 파일이 생성된다.

JAR 파일을 열어보면 MANIFEST.MF에 정의되어있는 클래스 파일 path에 , 의존성 라이브러리 path에 실제 컴파일된 코드와 jar 파일들이 위치해있는데, jar 파일 구성은 나중에 한번 더 정리해야겠다.

Archive:  hello.jar
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  01-04-2024 22:01   META-INF/
      553  01-04-2024 22:01   META-INF/MANIFEST.MF
...
     5871  02-01-1980 00:00   org/springframework/boot/loader/ClassPathIndexFile.class
     6806  02-01-1980 00:00   org/springframework/boot/loader/ExecutableArchiveLauncher.class
     3966  02-01-1980 00:00   org/springframework/boot/loader/JarLauncher.class
...
        0  01-04-2024 22:01   BOOT-INF/
        0  01-04-2024 22:01   BOOT-INF/classes/
        0  01-04-2024 22:00   BOOT-INF/classes/com/
...
        0  01-04-2024 22:01   BOOT-INF/lib/
    30398  11-06-2023 18:20   BOOT-INF/lib/spring-session-data-redis-2.4.3.jar
...
---------                     -------
 92716267                     279 files

 

참고로 META-INF/MANIFEST.MF 파일은 메타데이터를 저장하는 파일인데, 이것도 까보면 아래와 같다.

Manifest-Version: 1.0
Created-By: Apache Maven 3.8.1
Built-By: 
Build-Jdk: 11.0.17
Implementation-Title: {pom.xml에 정의한 <artifactId>}
Implementation-Version: {pom.xml에 정의한 <version>}
Implementation-Vendor-Id: {pom.xml에 정의한 <groupId>}
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: {pom.xml에 정의한 <mainClass>}
Spring-Boot-Version: 2.4.4
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
  • Main-Class: jar 파일 실행시 실행해야 하는 클래스들을 지정
  • Manifest-Version: 사용 중인 특정 매니페스트 파일 형식을 설명한다.

maven 레포지토리

maven 빌드가 진행되면서 각 단계에서 필요한 라이브러리를 레포지토리에서 찾아서 로컬에 다운로드하고 사용한다.

찾는 순서는 로컬 → 중앙 → 원격 순.

 

  • 로컬저장소 (local)
    • 사용자 로컬 디렉토리
    • 메이븐 처음 실행할 때 생성된다. -> USER_HOME/.m2/repository
    • 매번 원격 저장소에 접근하는 오버헤드를 줄여준다
  • 중앙저장소 (central)
  • 원격저장소 (remote)
    • 우리는 nexus 저장소를 사용하는데, 무료로 사용가능한 maven repository이다.
    • pom.xml에 아래처럼 정의해놓으면 된다.
<repositories>
    <repository>
        <id>~~~~~</id>
        <url>https://~~~~~~~~ </url>
    </repository>
<repositories>
Comments