본문 바로가기

개발/java

우린 Maven을 Maven(매번) 모르고 막 쓴다

※ 이 글은 jeong-pro.tistory.com/168 의 글을 참조하여 작성했습니다.

 

Maven은 뭘 하는 것일까? 플러그인을 연결해주는 플랫폼 정도는 다 알고 있다.

하지만, Maven은 어떻게 작동할까?

Maven의 한줄 한줄을 내가 해석할 수 있는가?

 

그저 인터넷에 있는 것을 그대로 복사 붙여넣기만 해오던 나 자신을 반성하며

미스터 메이븐과 인터뷰를 해보겠다.

Q. 안녕하세요 메이븐씨. 당신이 하는 일은 뭔가요?

A. 아, 저는 자바 프로젝트 빌드를 자동화 해주는 일을 하고 있어요.

 

Q. 주로 자동화 빌드를 할때 어떤 파일을 참조하시죠?

A. settings.xmlpom.xml을 가장 많이 보는 편이죠 !

    settings.xml은 제 자신(Maven)에 대한 설정을 기재해놓습니다.

    Maven디렉토리 / conf / 경로에 있고,

    사실 수정하거나 바뀔 일은 잘 없습니다.

    pom.xml은 프로젝트의 최상단 디렉토리에 위치해있습니다.

    Project Object Model의 줄임말이고, 프로젝트 내부 빌드옵션이 적혀 있습니다.

    아, 물론 pom.xml이라고 꼭 이름지을 필요는 없어요. 바꾸고 따로 설정해줄 수 있지만,

    많이들 이렇게 쓰시니까 일종의 관습이고 약속이 됐죠.

 

Q. 그렇군요. 그렇다면 평소에 쓰시는 pom.xml파일을 한번 설명해주실 수 있나요?

A. 물론이죠. 이 질문을 물어보는 사람이 정말 없는데 ㅠㅠ 너무 설명하고 싶었습니다.

    아래 코드를 보시죠! 스프링 부트 생성시 나오는 pom.xml입니다.

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
 
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
 
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

태그 하나하나 순서대로 살펴볼까요?

    <project>라는 태그가 전체를 감싸고 있구요,

    <modelVersion> : 4.0.0라고 써있고, maven의 pom.xml의 모델 버전입니다. 형식이 4.0.0 버전이라고 이해하면 되요.

    <groupId> : 프로젝트를 생성한 조직 또는 그룹명으로 보통, URL의 역순으로 지정해요..

    <artifactId> : 프로젝트에서 생성되는 기본 아티팩트의 고유 이름입니다.

                      메이븐에 의해 생성되는 일반적인 artifact는 <artifact>-<version>.<extention>이에요.

                      (ex demo-0.0.1-SNAPSHOT.jar)

    <version> : 애플리케이션의 버전. 접미사로 SNAPSHOT이 붙으면 아직 개발단계라는 의미이고,

                    메이븐이 개발단계에서는 라이브러리를 관리하는 방식이 달라요.

    <packaging> : jar, war, ear, pom등 패키지 유형을 나타내요.

    <name> : 프로젝트 이름입니다.

    <description> : 프로젝트 설명입니다.

    <url> : 프로젝트를 찾을 수 있는 URL이에요.

    위와 같은 태그들은 프로젝트 정보에 관련된 내용입니다.

 

    아래는 옵션인데요,

    * <properties> : pom.xml에서 중복해서 사용되는 설정(상수) 값들을 지정해놓는 부분입니다.

                          다른 위치에서 ${...}로 표기해서 사용할 수 있어요.

                         (java.version에 1.8을 적용하고 다른 위치에서 ${java.version}이라고 쓰면 "1.8"이라고 쓴 것과 같음)

    * <profiles> : 한 프로젝트에서 java의 버전을 나눠야할 때 아래와 같이 설정할 수 있어요.

<profiles>
  <profile>
   <id>dev</id>
   <properties>
    <java.version>1.8</java.version>
   </properties>
  </profile>
  <profile>
   <id>prod</id>
   <properties>
    <java.version>1.9</java.version>
   </properties>
  </profile>
</profiles>

    Maven은 자신의 명령어를 갖고 있고, 이 명령어들을 일련으로 입력하면서 자동 빌드를 하는데요,

    위 id 태그에 보면 dev와 prod 두가지 profile이 정의되어있죠?

    mvn compile -P prod 라는 명령어를 입력하면 ${java.version}은 1.9가 됩니다.

다음은 가장 많이 설정하는 <dependencies> 태그입니다.

    의존성 라이브러리 정보를 적어놓는데요,

    최소요건은 groupid, artifactid, version 이 세가지 입니다.

    (예제에 적혀있는 spring-boot-starter 같은 경우는 알아서 잘 맞는 버전으로 설정되기 때문에,

    문제가 생긴다면 그건 개발자가 오버라이드하거나 따로 설정을해서 생기는 문제입니다 호호)

    그리고 ! 라이브러리를 사용할 때 전제적으로 필요한 라이브러리가 있다면 알아서 가져오는 기능도 있습니다 !

    이 태그 속에 <scope> 라는 태그도 볼 수 있는데, complie, runtime, provided, test 등 고정값이 있어요.

    이 것은 이 라이브러리가 어떤 타이밍에 필요하고 제외되는지 적어놓는 거에요.

 

마지막은 핵심적인 <build> 태그입니다.

    maven의 핵심인 빌드와 관련된 정보를 설정하는 태그에요.

    이 부분을 이해하기 위해선 메이븐의 라이프사이클( = 작동 순서) 에 대해서 알 필요가 있습니다.

    maven이 빌드를 시작부터 끝내기 까지의 과정이 있겠죠?

    default -> clean -> site 의 순서로 진행됩니다.

 

    maven 은 자신의 명령어가 있고, 일련의 명령어를 통해 자동 빌드를 구현합니다.

단계 명령어 설명
default mvn process-resources resource 디렉토리에 있는 내용을 target/classes 로 복사합니다.
mvn compile src/java 의 자바 파일을 컴파일해서 target/classes로 복사합니다.
mvn process-testResources,
mvn test-compile
test/java 의 내용을 target/test-classes로 복사합니다.
mvn test arget/test-classes에 있는 테스트케이스의 단위테스트를 진행합니다.
결과는 target/surefile-reports에 생성합니다.
mvn package target 디렉토리 하위에 jar, war, ear등 패키지 파일을 생성합니다.
파일 이름은 <build>의 <fileName> 값을 참조합니다.
값이 없을 시 artifactId-version.extention 이름을 참조합니다.
mvn install 로컬 저장소로 배포합니다.
mvn deploy 원격 저장소로 배포합니다.
clean mvn clean 빌드 과정에 생긴 target 디렉토리를 삭제합니다.
site mvn site target/site에 문서 사이트를 생성합니다.
mvn site-deploy 문서 사이트를 서버로 배포합니다.

 

 

[출처 : https://www.slideshare.net/ssuser5445b7/ss-56566336?qid=927855f5-7c8a-4f88-a834-d31292324fd2&v=&b=&from_search=4]

 

    라이프 사이클을 도식화 하면 위와 같이 되겠죠?

 

    이제 <build> 태그 속 태그들을 확인해볼까요? (*표시는 선택입력입니다.)    -*<fileName> 빌드 결과물의 이름을 지정합니다.    -*<resources> 리소스의 위치를 지정합니다. default값은 "src/main/resources" 입니다.    -*<testResources> 테스트 리소스의 위치를 지정해요. default값은 "src/test/resources"에요.    -*<Repositories> 빌드할 때 접근할 저장소의 위치를 지정합니다.                          default값은 메이븐 중앙 저장소인 http://repo1.maven.org/maven2 입니다.    -*<outputDirectory> 컴파일 결과물 위치값을 지정합니다. default는 "target/classes"입니다.    -*<testOutputDirectory> 테스트 소스 컴파일 결과물 위치값을 지정합니다. "target/test-classes"    -<plugin> 가장 중요합니다. 메이븐의 모든 기능은 플러그인을 기반으로 작동하기 때문이죠.                  플러그인마다 형식에 대한 안내가 나와있으니 참고하셔서 작성하세요.                  --<executions> 플러그인 goal 과 관련된 실행에 대한 설정입니다.                  --<configuration> 플러그인에서 필요한 설정값을 지정합니다.

 

    사이트로 배포한다면 <distributionManagement> 태그를 사용할 수 있습니다.

<project>
  ...
  <distributionManagement>
    <site>
      <id>website</id>
      <url>scp://www.mycompany.com/www/docs/project/</url>
    </site>
  </distributionManagement>
  ...
</project>

Q. 귀한 시간 내주셔서 상세한 설명 감사합니다!

A. 네. pom.xml 관한 내용과 Maven의 라이프사이클을 꼭 기억해주세요!

    감사합니다!

 

 

 

반응형