Maven 정리

Q·2023년 2월 8일
0

JAVA 관련 CS

목록 보기
3/4

Maven

Maven 은 Apache Ant 의 대안으로 만들어졌다 (Ant는 많은 스크립트 작성과 라이브러리 의존관리가 되지 않아 불편했기 때문)

초기의 java 빌드도구로 Ant 를 많이 사용하였으나 최근 많은 빌드도구들이 생겨나 Maven 이 많이 쓰였고, 현재는 Gradle 이 많이 쓰인다. (Gradle이 Maven보다 빌드 스피드가 최대 100배 빠르다고 하다.)

라이프 사이클

Maven LifeCycle

Clean빌드 시 생성되었던 파일들 삭제하는 단계 (target 폴더 삭제)
Validate프로젝트가 올바른지 확인하고 필요한 모든 정보를 사용할 수 있는 지 확인하는 단계
Compile프로젝트의 소스 코드를 컴파일 하는 단계
Test유닛(단위) 테스트를 수행 하는 단계 (테스트 실패시 빌드 실패로 처리, 스킵 가능)
Package실제 컴파일된 소스 코드와 리소스들을 jar, war 등등의 파일 등의 배포를 위한 패키지로 만드는 단계
Verify통합 테스트 결과에 대한 검사를 실행하여 품질 기준을 충족하는지 확인하는 단계
Install패키지를 로컬 저장소에 설치하는 단계 ( compile + package )
Site프로젝트 문서와 사이트 작성, 생성하는 단계
Deploy만들어진 package 를 원격 저장소에 release 하는 단계
  • 빌드 시 생성되었던 산출물을 삭제
    • pre-clean : clean 작업 전에 사전작업
    • clean : 이전 빌드에서 생성된 모든 파일 삭제
    • post-clean : 사후작업
  • default : 프로젝트 배포절차, 패키지 타입별로 다르게 정의됌
    • validate : 프로젝트 상태 점검, 빌드에 필요한 정보 존재유무 체크
    • initialize : 빌드 상태를 초기화, 속성 설정, 작업 디렉터리 생성
    • generate-sources : 컴파일에 필요한 소스 생성
    • process-sources : 소스코드를 처리
    • generate-resources : 패키지에 포함될 자원 생성
    • compile : 프로젝트의 소스코드를 컴파일
    • process-classes : 컴파일 후 후처리
    • generate-test-source : 테스트를 위한 소스 코드를 생성
    • process-test-source : 테스트 소스코드를 처리
    • generate-test-resources : 테스팅을 위한 자원 생성
    • process-test-resources : 테스트 대상 디렉터리에 자원을 복사하고 가공
    • test-compile : 테스트 코드를 컴파일
    • process-test-classes : 컴파일 후 후처리
    • test : 단위 테스트 프레임워크를 이용해 테스트 수행
    • prepare-package : 패키지 생성 전 사전작업
    • package : 개발자가 선택한 war, jar 등의 패키징 수행
    • pre-integration-test : 통합테스팅 전 사전작업
    • integration-test : 통합테스트
    • post-integration : 통합테스팅 후 사후작업
    • verify : 패키지가 품질 기준에 적합한지 검사
    • install : 패키지를 로컬 저장소에 설치
    • deploy : 패키지를 원격 저장소에 배포
  • site : 프로젝트 문서화 절차
    • pre-site : 사전작업
    • site : 사이트문서 생성
    • post-site : 사후작업 및 배포 전 사전작업
    • site-deploy : 생성된 문서를 웹 서버에 배포

최종 빌드 순서

compile > test > package

  1. compile : src/main/java 디렉토리 아래의 모든 소스 코드가 컴파일
  2. src/test/java, src/test/resources 테스트 자원 복사 및 테스트 소스 코드 컴파일
  3. junit: 단위 테스트 프레임워크, 테스트 단계를 거치기 위해 의존 설정을 해준다
  4. packaging: 컴파일과 테스트가 완료된 후, jar, war 같은 형태로 압축하는 작업

페이즈(Phase) = 단계

  • Build Lifecycle 의 각각의 단계를 Phase 라고 한다 (pre-integratuin-test, install ... 등)
  • Phase는 의존관계를 가지고 있어 해당 Phase 가 수행되려면 이전 단계의 Phase가 모두 수행되어야 한다
  • 즉, 모든 빌드단계는 이전 단계가 성공적으로 실행되었을 때 실행된다는 것이 Dependency 이다

골(Goal) = 실행

  • 특정 작업, 최소한의 실행 단위(task)
  • 하나의 플러그인에서는 여러 작업을 수행할 수 있도록 지원하며, 플러그인에서 실행할 수 있는 각각의 기능(명령)을 Goal이라고 한다

POM (Project Object Model)

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion> <!--POM model의 버전-->
    <parent> <!--프로젝트의 계층 정보-->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.god</groupId> <!--프로젝트를 생성하는 조직의 고유 아이디를 결정한다. 일반적으로 도메인 이름을 거꾸로 적는다.-->
    <artifactId>bo
    </artifactId> <!--프로젝트 빌드시 파일 대표이름 이다. groupId 내에서 유일해야 한다.Maven을 이용하여 빌드시 다음과 같은 규칙으로 파일이 생성 된다. artifactid-version.packaging. 위 예의 경우 빌드할 경우 bo-0.0.1-SNAPSHOT.war 파일이 생성된다.-->
    <version>0.0.1-SNAPSHOT</version> <!--프로젝트의 현재 버전, 프로젝트 개발 중일 때는 SNAPSHOT을 접미사로 사용-->
    <packaging>war</packaging> <!--패키징 유형(jar, war, ear 등)-->
    <name>bo</name> <!--프로젝트, 프로젝트 이름-->
    <description>Demo project for Spring Boot</description> <!--프로젝트에 대한 간략한 설명-->
    <url>http://goddaehee.tistory.com</url> <!--프로젝트에 대한 참고 Reference 사이트-->
    <properties> <!-- 버전관리시 용이 하다. ex) 하당 자바 버전을 선언 하고 dependencies에서 다음과 같이 활용 가능 하다. <version>${java.version}</version> -->
        <java.version>1.8</java.version>
    </properties>
    <dependencies> <!--dependencies태그 안에는 프로젝트와 의존 관계에 있는 라이브러리들을 관리 한다.-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build> <!--빌드에 사용할 플러그인 목록-->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Maven Element

modelVersionPOM model 의 버전
parent프로젝트의 계층 정보
groupId프로젝트를 생성하는 조직의 고유 아이디
일반적으로 도메인 이름을 거꾸로 적는다
예시) naver.com -> com.naver
artifactId프로젝트 빌드 시 파일 대표 이름.
groupId 내에서 유일해야 한다
Maven 을 이용하여 빌드 시 다음과 같은 규칙으로 생성

artifactid-version.packaging

위 예의 경우 빌드 할 경우 bo-0.0.1-SNAPSHOT.war 파일 생성
version프로젝트의 현재 버전, 프로젝트 개발 중 일 때는 SNAPSHOT 을 접미사로 사용
packaging패키징 유형 (jar, war, ear 등)
jar = java 실행
war = tomcat 실행
name프로젝트, 프로젝트 이름
description프로젝트에 대한 간략한 설명
url프로젝트에 대한 참고 Reference 사이트
properties버전관리시 용이하다
예시) 동일한 버전을 중복으로 계속 적는 경우(spring mvc, spring context, spring jpa ... 등)
dependencies라이브러리들을 관리한다
build빌드에 사용할 플러그인 목록

TIP
기본적으로 . 패키지에 파일을 생성한다
위 예시에서는 com.god.bo 위치에 clsss 가 생성된다

scope

Scope Value

compiledefault scope
<scope></scope> 를 작성하지 않아도 기본값
모든 상황에서 포함됨
providedcompile 과 유사하게 모든 상황에서 수행됨

하지만, 다른 외부 컨테이너에서 기본 제공되는 API 인 경우 provided 를 지정 시 마지막 패키징 할 때 포함되지 않음

예를들어 tomcat 에서 기본적으로 servlet api 를 제공하기 때문에 servlet api 를 provided 로 지정하면 패키징시 제외한다
runtime컴파일 시에는 불필요하고, 실행 시 필요한 경우
런타임 및 테스트 시 classpath 에 추가 되지만, 컴파일시에는 추가되지 않음
test테스트 시 에만 사용
systemprovided 와 유사
system 의 특정 path 를 참조하도록 지정
Maven central repository 를 사용하지 않음
importscope 는 dependencyManagement 섹션에서 pom 의 의존관계에 대해 사용

플러그인

Compile Plugin

  • 기본적으로 maven 은 jdk 1.5 기준으로 compile 을 시도한다
  • 1.5 버전 보다 더 높은 버전으로 compile 하기 위해서는 다음과 같은 조치가 필요하다
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.5.1</version>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
        <compilerArgument>-Xlint:all</compilerArgument>
        <showWarnings>true</showWarnings>
        <showDeprecation>true</showDeprecation>
    </configuration>
</plugin>

Jar Plugin

  • jar 패키징된 파일을 실행하기 위해서 ManifestFile 을 생성해주는 plugin
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>HelloWorld</mainClass>
        </manifest>
      </archive>
    </configuration>
</plugin>  

Source Plugin

  • package 시에 Source 코드를 포함한다
  • 아래의 코드를 추가하면 package 수행 및 install 수행 시 기본jar명-sources.jar 파일이 추가로 하나 생성된다
  • 내부에 설정은 plugin 별로 고유의 goal 이 있다
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>3.0.1</version>
    <executions>
        <execution>
            <id>attach-resources</id>
            <phase>package</phase>
            <goals>
                    <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

spring boot plugin

  • jar 파일에서 spring boot 를 실행 시킬 수 있게 해주는 플러그인
  • execution 는 maven lifecycle pre intergration 에서 spring boot 를 start 하고, post intergration test 에서 stop 하기 위함 (빌드 테스트 과정이라고 생각하면 된다)
  • lombok 은 제외시킴
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>pre integration test</id>
            <goals>
                <goal>start</goal>
            </goals>
        </execution>
        <execution>
            <id>post integration test</id>
            <goals>
                <goal>stop</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <excludes>
            <exclude>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </exclude>
        </excludes>
    </configuration>
</plugin>

resource plugin

  • 원하는 파일을 원하는 위치에 복사할 수 있다
  • 주로 compile 될 때 생성되는 target/classes 에 복사할 때 사용한다
  • jar 파일 또는 war 로 파일로 묶이기 전에 파일을 복사해주어야 하기 때문에 prepare-package phase 단계에서 진행
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>copy front-end template</id>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <phase>prepare-package</phase>
            <configuration>
                <outputDirectory>${basedir}/src/main/resources/templates</outputDirectory>
                <resources>
                    <resource>
                        <directory>${basedir}/../frontend/dist</directory>
                        <includes>
                            <include>index.html</include>
                        </includes>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

위의 예시는 vue 에서 build 된 dist 폴더에서 spring/resource 폴더로 복사하는 예시이다

예시로 1개 보여줬지만 target/classes 에도 복사를 해주어야 한다

exec plugin

  • 외부 프로그램을 실행 하거나 현재 VM 에 있는 메인 클래스 실행할 때 사용

PlugIn Element

<executions>실행 목록들
<execution>실행 설정
<id>id (중복불가)
<goal>exec (외부프로그램 실행)
help (exec 플러그인 도움말 보기)
java (현재 VM 에 있는 메인 클래스 실행)
<phase>해당 페이즈 단계에서 실행
<plugin.configuration>workingDirectory : 해당 명령을 실행할 위치를 설정
<execution.configuration>executable : 실행할 파일명
argument : 실행 파일에 넘겨줄 인자 설정
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.6.0</version>
    <executions> 
        <execution>
            <id>front-end install</id>
            <goals>
                <goal>exec</goal>
            </goals>
            <phase>prepare-package</phase>
            <configuration>
                <executable>npm</executable>
                <arguments>
                    <argument>install</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <workingDirectory>${basedir}/../frontend</workingDirectory>
    </configuration>
</plugin>

위 예시는 pom.xml/../frontend 폴더에서 npm install 명령 실행하라는 의미이다

execution 순서는 맨 위에 있는 executuin 이 먼저 실행 된다 (순서 유의)

profile
Data Engineer

0개의 댓글