Maven Lifecycle이 왜 중요한가?

Maven의 Lifecycle은 Maven의 동작하는 중요 원리를 이해하는 것이기 때문에 중요합니다.

  • Maven은 동작시 표준화된 생명주기를 가지고 있으며 이를 Phase라고도 한다.
  • 개발자는 특정 Phase를 호출할 수 있다(예; mvn compile).
  • 대부분의 Maven Plugin은 특정 Phase에 맞춰서 동작하도록 설계되어 있다.
    • 기존의 빌드 도구는 Phase를 개발자가 임의대로 만들어서 사용했기 때문에 빌드 과정이 표준화되지 못했다.
    • 이런 이유로 각 회사마다, 각 개발자마다 각기 다른 빌드 스크립트를 작성하였고, 빌드 스크립트 구조나 코드 작성 방법도 서로 매우 상이하였다.
    • Maven은 표준화된 Lifecycle을 가지고 있고 그것에 맞춰서 Plugin이 동작하는 구조로 되어 있어서 Plugin을 만들기만 하면 기능을 무궁무진하게 확장할 수 있다.
    • 이러한 일을 주도적으로 하는 것이 Maven 내부에 포함되어 있는 Plexus Container이다.
  • 특정 Phase가 되면 해당 Maven Plugin이 실행된다. 예를 들어 Maven Compile Plugin은 compile Phase를 포함하여 컴파일과 관련된 모든 Phase에서 상황에 맞춰서 동작한다.

Maven Lifecycle과 Plugin의 동작 원리

다음은 아주 간단한 그림으로 Maven 동작 순서가 이미 고정되어 있습니다. Maven은 동작 생명 주기를 phase로 구분해두었고 특정 phase가 되면 이벤트가 발생하고 해당 이벤트를 받아서 플러그인이 동작합니다. 그래서 플러그인을 개발하는 개발자는 플러그인에 기능을 넣으면서 언제 동작할지를 결정합니다. 또한 플러그인에는 하나 이상의 단위 기능을 포함하고 있는데 단위 기능을 goal이라고 합니다. 따라서 모든  Maven Plugin은 하나 이상의 goal을 구현하고 있습니다. 예를 들어 소스코드를 컴파일 하는 기능이 독립적인 단위 기능이면 이 기능을 goal로 정의할 수 있습니다. 이렇듯 maven plugin을 구현하는 개발자는 자신만의 단위 기능을 goal로 정의하고, 이 goal이 어느 phase때 동작해야하는지를 명시합니다. 그러면 해당 phase가 되면 goal이 자동으로 실행됩니다. 물론 해당 maven plugin의  goal이 실행되려면 Maven POM의 빌드 설정에 plugin을 추가해야 합니다. 다음의 도식을 보면 좌측에는 phase가, 우측에는 goal이 매핑되어 있습니다. Apache Maven을 개발하는 개발자들은 Maven Plugin을 다양하게 개발하여 처음에 제공했습니다. 대표적으로 컴파일하는 Maven Compiler Plugin이 되겠습니다. Maven은 Ant와 다르게 Maven Core만 포함되어 있고 plugin은 모두 인터넷으로 다운로드하며, 처음부터 제공하는 Maven Plugin은 이미 Maven Core와 잘 결합하여 동작하도록 네이밍이 표준화되어 있습니다.

다음은 전체 phase에 대해서 Maven Plugin을 매핑한 도식입니다. 파란색으로 표시되어 있는 phase는 가장 기본이 되는 phase라고 할 수 있겠습니다.

Maven Phase의 종류

다음은 Maven의 Lifecycle입니다. Phase라고 부르는 것이 Lifecycle을 처리하는 단계로 보면 되며 Phase = Lifecycle로 봐도 무방합니다. 또한 개발자는 Phase를 직접 지정하여 해당 단계를 까지 실행할 수 있습니다. 다음에서 파란색으로 표시한 Phase는 가장 많이 사용하는 Phase입니다. 예를 들어 compile Phase를 실행하면 validate → compile 까지 실행됩니다. 실행은 mvn compile 로 Maven을 실행하면 됩니다.

PhaseDescription
validateValidation of project is carried out and provides the necessary information required to complete the build process.
generate-resourcesSource code generation to include while compiling.
process-sourcesSource code is processed.
generate-resourcesResource generation to include in packages.
process-resourcesResources packing and copying into destination directory and is ready for package.
compileSource code compilation
process-classesGenerated files into post-process after compilation.
generate-test-sourcesTest source generation to include in compilation.
process-test-sourcesProcessing the test source code.
generate-test-resourcesCreation of resources to test.
process-test-resourcesCopying and processing the resources to test destination.
test-compileCompiling the test source code to test destination.
testWith unit testing framework, one can run the tests.
prepare-packagePreparing the package by performing operations before actual packaging.
packageGather the compiled code and package in JAR,WAR or EAR.
pre-integration testThe actions to be performed before integration tests are executed like setting the environment.
integration testProcessing and deploying the package.
post-integration testPerforming the action after executing the integration tests like cleaning the environment.
verifyChecking the packages are valid or not.
installInstalling the package into local repository.
deployCopying the package into remote repository.

IntelliJ IDEA의 Maven

다음은 IntelliJ IDEA의 Maven 기능에서 제공하는 Lifecycle 화면으로써 Maven에서 지원하는 모든 Maven Lifecycle을 제공하기 보다는 가장 많이 사용하는 Lifecycle만 제공합니다.

만약에 수동으로 Maven의 다른 lifecycle을 직접 호출하는 경우 IntelliJ IDEA에서 다음과 같이 Run/Debug Configuration을 Maven으로 생성하여 직접 지정하면 됩니다.