Build Java Projects with Maven
Introduction to Java Build Tools
ဒီသင်ခန်းစာမှာ Java ecosystem ထဲမှာ အသုံးပြုတဲ့ build tools တွေကို မိတ်ဆက်ပေးထားပါတယ်။ Software ကို ဘယ်လို ရေးသားကြတယ်ဆိုတာကို အကျဉ်းချုပ် ပြောပြရရင်၊ Software တွေကို တစ်ဦးတစ်ယောက်တည်း ရေးတာမျိုးမဟုတ်ဘဲ အဖွဲ့အစည်းတွေ၊ လူအများကြီးက အတူတကွ ပူးပေါင်း ရေးသားကြပါတယ်။ ဒါ့အပြင် ရှေ့ပြေးစမ်းသပ်ပြီး ပြန်လည်ထုတ်လုပ်ထားတဲ့ software components တွေပေါ်မှာ အခြေခံပြီး ရေးသားကြတာ ဖြစ်ပါတယ်။ ဒီအချက်ဟာ တက္ကသိုလ်ကျောင်းသားဘဝမှာ software ရေးသားပုံနဲ့ သိသိသာသာ ကွာခြားပါတယ်။ အသစ်ဝင်လာတဲ့သူတွေအနေနဲ့ အလုပ်ခွင်မှာ build ecosystem နဲ့ ပတ်သက်ပြီး အခက်အခဲတွေ ကြုံရတတ်ပါတယ်။
Build system ရဲ့ အရေးကြီးတဲ့ အစိတ်အပိုင်းတစ်ခုက build tool ဖြစ်ပါတယ်။ Java project တွေအတွက် အများဆုံးအသုံးပြုတဲ့ build tool ကတော့ Maven ပဲ ဖြစ်ပါတယ်။ Maven က build tool တစ်ခုတည်းတင်မကဘဲ project တစ်ခုလုံးကို စီမံခန့်ခွဲနိုင်ပါတယ်။ Maven နဲ့ ဆင်တူတဲ့ tools တွေထဲမှာ Ant, Gradle, Ivy, Gulp, Grunt, Leiningen, GNU Make တို့ ပါဝင်ပါတယ်။

ဒီသင်ခန်းစာမှာတော့ build system နဲ့ ပတ်သက်တဲ့ အဓိပ္ပာယ်ရှိတဲ့ အခြားသော အသုံးအနှုန်းတွေကို စတင်ရှင်းပြပေးမှာ ဖြစ်ပါတယ်။ Build system ဆိုတာက software ကို တည်ဆောက်ရာမှာ အသုံးပြုတဲ့ စနစ်တစ်ခုဖြစ်ပြီး၊ ဒီစနစ်ထဲမှာ သုံးတဲ့ အဓိပ္ပာယ်ရှိတဲ့ စကားလုံးတွေကို နားလည်ဖို့က အရေးကြီးပါတယ်။
Build
Build ဆိုတာက software ဖန်တီးရာမှာ source code ဖိုင်တွေကို standalone software artifacts (ကွန်ပျူတာပေါ်မှာ run လို့ရတဲ့ software) တွေဖြစ်အောင် ပြောင်းလဲတဲ့ လုပ်ငန်းစဉ်ဖြစ်ပါတယ်။ ဒီ artifact ကိုလည်း build လို့ပဲ ခေါ်ပါတယ်။ အဖွဲ့အစည်းတစ်ခုမှာဆိုရင် များသောအားဖြင့် codebase တစ်ခုထဲမှာ branch တွေ အများကြီး ရှိနေနိုင်ပြီး၊ တစ်နေ့တာအတွင်း nightly builds တွေ ဖြစ်ပေါ်ကာ stage, test, production စတဲ့ ပတ်ဝန်းကျင်တွေမှာ deploy လုပ်ကြပါတယ်။
Nightly builds ဆိုတာက software ကို ညတိုင်း အလိုအလျောက် build လုပ်တဲ့ လုပ်ငန်းစဉ်ဖြစ်ပြီး၊ အများအားဖြင့် development branch တွေမှာရှိတဲ့ latest code တွေကို အသုံးပြုပါတယ်။ ဒီ nightly builds တွေက integration ပြဿနာတွေကို မကြာခဏ စစ်ဆေးနိုင်ဖို့၊ စမ်းသပ်ခြင်းနဲ့ deployment အတွက် တည်ငြိမ်ပြီး အသစ်ပြန်ပြင်ထားတဲ့ version ကို ပေးစွမ်းပါတယ်။
Build Tool
Build tool ဆိုတာက build လုပ်ငန်းစဉ်ကို စီမံခန့်ခွဲတဲ့ program တစ်ခုဖြစ်ပြီး၊ အခြား program တွေကို coordinate လုပ်ပြီး ထိန်းချုပ်ပေးပါတယ်။ Make, Gradle, Meister by OpenMake Software, Ant, Maven, Rake, SCons, and Phing စတဲ့ tools တွေက build tool တွေ ဖြစ်ပါတယ်။ Build tool တွေက ဖိုင်တွေကို မှန်ကန်တဲ့ အစီအစဥ်အတိုင်း compile လုပ်၊ dependency တွေကို download လုပ်၊ unit နဲ့ integration tests တွေကို run လုပ်ပြီး deploy လုပ်နိုင်တဲ့ binaries တွေ ထုတ်ပေးပါတယ်။
Artifact
Artifact ဆိုတာက လက်တင်စကားလုံး arte factum ကနေ ဆင်းသက်လာတာဖြစ်ပြီး arte က skill၊ factum က to make လို့ အဓိပ္ပာယ်ရပါတယ်။ Software development လုပ်ငန်းစဉ်မှာ artifact တွေက design documents, data models, workflow diagrams, test plans, setup scripts, compiled binaries, software packages စတဲ့ လူတွေ ဖန်တီးတဲ့ အရာတွေ ဖြစ်ပါတယ်။ အများအားဖြင့် artifact တွေကို shared drive ဒါမှမဟုတ် document repository တစ်ခုမှာ သိမ်းဆည်းပြီး တခြားသူတွေ ကြည့်ရှုနိုင်အောင် ထားရှိကြပါတယ်။ Artifact တွေက code library ရဲ့ released code ဒါမှမဟုတ် program ရဲ့ released executable ဖြစ်နိုင်ပါတယ်။
Build Automation
Build automation ဆိုတာက software build ဖန်တီးခြင်းနဲ့ ဆက်စပ်တဲ့ လုပ်ငန်းစဉ်တွေကို အလိုအလျောက် လုပ်ဆောင်ခြင်း (automation) ဖြစ်ပြီး၊ source code ကို binary code အဖြစ် compile လုပ်ခြင်း၊ binary code ကို package လုပ်ခြင်း၊ automated tests တွေကို run လုပ်ခြင်း တို့ ပါဝင်ပါတယ်။ Build automation မှာ final artifact ကို လူသားရဲ့ ဝင်ရောက်စွက်ဖက်မှု မလိုဘဲ source code control repository မှာရှိတဲ့ အချက်အလက်တွေပဲ အသုံးပြုပြီး အချိန်မရွေး ပြုလုပ်နိုင်ပါတယ်။
CI/CD

CI/CD ဆိုတာ Continuous Integration နဲ့ Continuous Delivery/Deployment ကို ရည်ညွှန်းပြီး build နဲ့ build automation တွေနဲ့ ပတ်သက်တဲ့ အသုံးအနှုန်းဖြစ်ပါတယ်။ Maven က CI/CD pipeline ထဲမှာ အရေးပါတဲ့ အစိတ်အပိုင်းတစ်ခုဖြစ်ပြီး၊ developer ရဲ့ IDE မှာ ရေးသားတဲ့ code ကနေ production အထိ ဘယ်လိုရောက်ရှိသွားတာကို နားလည်ဖို့ အရေးကြီးပါတယ်။ CI/CD pipeline ရဲ့ ရည်ရွယ်ချက်ကတော့ အဖွဲ့တွေ code changes တွေကို ပိုမိုမြန်ဆန်ပြီး မကြာခဏ ပေးပို့နိုင်ဖို့ ဖြစ်ပါတယ်။ CI/CD pipeline မှာ continuous development, continuous testing, continuous integration, continuous deployment, continuous monitoring စတဲ့ လုပ်ငန်းစဉ်တွေ ပါဝင်ပါတယ်။
CI ဆိုတာ Continuous Integration ကို ဆိုလိုပြီး developer တွေ code ကို check-in လုပ်တဲ့ အလိုအလျောက် လုပ်ငန်းစဉ်ဖြစ်ပါတယ်။ CI အောင်မြင်ခြင်းဆိုတာ code changes တွေကို ပုံမှန် build, test, merge လုပ်ပြီး shared repository မှာ ထည့်သွင်းခြင်းဖြစ်ပြီး integration hell ဆိုတဲ့ ပြဿနာကို ဖြေရှင်းပေးပါတယ်။
CD ဆိုတာ Continuous Delivery နဲ့ Continuous Deployment ကို ရည်ညွှန်းပြီး pipeline ရဲ့ နောက်ပိုင်း automation လုပ်ငန်းစဉ်တွေကို ဖော်ပြပါတယ်။
Continuous Delivery မှာ developer ရဲ့ code changes တွေကို အလိုအလျောက် bug test လုပ်ပြီး code repository (ဥပမာ- GitHub ဒါမှမဟုတ် Perforce) မှာ upload လုပ်ပေးပါတယ်။ ဒီ upload လုပ်ထားတဲ့ code တွေကို operations team က staging သို့မဟုတ် live production environment မှာ deploy လုပ်နိုင်ပါတယ်။ Continuous delivery ရဲ့ ရည်ရွယ်ချက်ကတော့ အသစ်ထည့်တဲ့ code ကို deploy လုပ်ရာမှာ အနည်းဆုံး ကြိုးစားမှုနဲ့ ပြုလုပ်နိုင်ဖို့ ဖြစ်ပါတယ်။ သို့သော် continuous delivery မှာ deployment က code repository မှာ ရပ်တန့်သွားပါတယ်။
Continuous Deployment က continuous delivery ရပ်တန့်ရာကနေ ဆက်လက်ပြီး developer ရဲ့ code changes တွေကို အလိုအလျောက် production environment မှာ release လုပ်ပေးတာဖြစ်ပြီး၊ ထို code တွေကို customer တွေ အသုံးပြုနိုင်ပါတယ်။ တစ်ခါတလေ continuous deployment ဆိုတဲ့ term ကို continuous delivery လုပ်ငန်းစဉ်နဲ့လည်း တွဲဖက်သုံးတတ်ကြပါတယ်။
CI/CD ဆိုတာကို Continuous Integration, Continuous Delivery, Continuous Deployment ဆိုတဲ့ သုံးခုလုံးကို ဖော်ပြတဲ့ term အနေနဲ့ အသုံးပြုကြပြီး၊ ဒီလုပ်ငန်းစဉ်ကို automation နဲ့ continuous monitoring အများကြီး ပါဝင်တဲ့ pipeline တစ်ခုအဖြစ် တွေးနိုင်ပါတယ်။ Maven ကတော့ ဒီ CI/CD pipeline ထဲမှာ အရေးပါတဲ့ အစိတ်အပိုင်းတစ်ခု ဖြစ်ပါတယ်။
Conclusion
Maven သည် နှစ်ပေါင်းများစွာအတွင်း လူကြိုက်များလာခဲ့ပြီး၊ ၎င်း၏ အောင်မြင်မှု အဓိကအကြောင်းရင်းမှာ ဆော့ဖ်ဝဲလ် တည်ဆောက်ရာတွင် အသုံးပြုနိုင်သော ပုံမှန်အင်တာဖေ့စ် (standardized interface) တစ်ခုကို သတ်မှတ်ပေးထားခြင်း ဖြစ်သည်။ Maven ၏ ဉာဏ်ကြီးမှုသည် ၎င်းအသုံးပြုသော plugin များတွင် ပါဝင်ပြီး၊ ဤ plugin များကို Maven repository မှ ရယူနိုင်သည်။ Maven သည် ပုံမှန် build လုပ်ငန်းများကို plugin များအဖြစ် ခွဲထုတ်ထားပြီး၊ ၎င်း plugin များကို Maven မှ တိုက်ရိုက် ခေါ်ယူအသုံးပြုနိုင်သည်။ Plugin များကို ဗဟိုစီမံခန့်ခွဲပြီး၊ အားလုံးနှင့် မျှဝေထားကြသည်။ ၎င်း plugin များအကြောင်းကို နောက်သင်ခန်းစာတွင် ဆက်လက်လေ့လာမည်ဖြစ်သည်။
Plugins and Goals
Plugin
Plugin ဆိုတာက Maven မှာ အလုပ်တစ်ခုခုလုပ်ဖို့ အသုံးပြုတဲ့ အပိုင်းလေးတွေပါ။ Maven ရဲ့ အခြေခံအစိတ်အပိုင်းတွေက နည်းနည်းသာရှိပြီး အများကြီးလုပ်ဆောင်တာတွေကို Plugins တွေက လုပ်ပေးပါတယ်။
ဥပမာ - Compiler Plugin က code တွေကို compile လုပ်ဖို့၊ Jar Plugin က jar ဖိုင်တွေ ဖန်တီးဖို့၊ Surefire Plugin က unit test တွေ run ဖို့ အသုံးပြုပါတယ်။
Plugins တွေကို မိမိတို့လိုအပ်သလို ရေးသားလည်း ရနိုင်ပါတယ်။ Plugins တွေက build လုပ်စဉ်အတွင်း လုပ်ဆောင်ဖို့လိုတဲ့ logic တွေကို code အဖြစ် ထည့်သွင်းထားတာတွေပါ။
Goal
Maven plugin တစ်ခုမှာ goals တွေ ပါဝင်ပြီး၊ goal ဆိုတာက အလုပ်တစ်ခုချင်းစီဖြစ်ပါတယ်။ Goal ကို plugin ရဲ့ စွမ်းဆောင်ရည်တစ်ခုအဖြစ် တွေးနိုင်ပြီး၊ POM ဖိုင် (နောက်ပိုင်းမှာ ရှင်းပြမယ်) မှာ သတ်မှတ်ထားတဲ့ project ပေါ်မှာ လုပ်ဆောင်ချင်တဲ့ အရေးယူချက်တစ်ခုလည်း ဖြစ်ပါတယ်။
ဒီအောက်မှာ ပုံဖော်ထားတာက ကျွန်တော်တို့ ပြောခဲ့တဲ့ အရာတွေကြား ရှိတဲ့ ဆက်နွယ်မှုကို ဖော်ပြတာပါ။ Maven ရဲ့ core, plugins, goals တွေဟာ ဘယ်လိုဆက်စပ်ပြီး အလုပ်လုပ်ကြောင်းကို ပြသပါတယ်။ Plugin တစ်ခုမှာ goals တွေ ပါဝင်ပြီး၊ goal တစ်ခုချင်းစီက plugin ရဲ့ တာဝန်တစ်ခုဖြစ်ပါတယ်။ ဒီပုံက Maven ရဲ့ အခြေခံ အစိတ်အပိုင်းတွေကြား ဆက်နွယ်မှုကို နားလည်ဖို့ အကူအညီဖြစ်စေပါတယ်။

Maven ရဲ့ help plugin ကို အသုံးပြုပြီး တစ်ခုချင်း plugin ထဲမှာ ရှိတဲ့ goals တွေကို စစ်ဆေးနိုင်ပါတယ်။ ဥပမာ၊ compiler plugin ရဲ့ goals တွေကို ကြည့်ချင်ရင် အောက်ပါ command ကို အသုံးပြုနိုင်ပါတယ်
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin
ဒီ command က help plugin ရဲ့ describe goal ကို ခေါ်သုံးတာဖြစ်ပြီး help:describe လို့ ဖော်ပြထားပါတယ်။ ဒီ goal က command line ကနေ argument တွေကို လက်ခံပြီး၊ -D နဲ့ စတင်တဲ့ argument တွေကို သတ်မှတ်နိုင်ပါတယ်။ ဥပမာ -Dplugin ဆိုတာက ကျွန်တော်တို့ သိချင်တဲ့ plugin ရဲ့ အသေးစိတ်အချက်အလက်တွေကို ဖော်ပြဖို့ သတ်မှတ်တဲ့ argument ဖြစ်ပါတယ်။
Output:

ဒီမှာ -Ddetail ဆိုတဲ့ argument ကို ပေါင်းထည့်တာနဲ့ output မှာ plugin ရဲ့ goal တစ်ခုချင်းစီအကြောင်း အသေးစိတ် ဖော်ပြပေးမှာ ဖြစ်ပါတယ်။ အဓိကအားဖြင့်
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin -Ddetail
ဆိုတဲ့ command က compiler plugin ရဲ့ goal တွေကို ပိုမိုအသေးစိတ် ဖော်ပြပေးတာ ဖြစ်ပါတယ်။
Output:

စိတ်ဝင်စားစရာကောင်းတာကတော့ help plugin ရဲ့ goals တွေကိုလည်း help plugin ကိုယ်တိုင်ကို အသုံးပြုပြီး စစ်ဆေးနိုင်ပါတယ်။ အောက်ပါ command က help plugin ရဲ့ goals တွေကို ပြသပေးမှာ ဖြစ်ပါတယ်။
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-help-plugin
ဒါက help plugin ကို အသုံးပြုပြီး help plugin ရဲ့ capabilities တွေကို ကြည့်ရှုနိုင်တဲ့ နည်းလမ်းဖြစ်ပါတယ်။

အကျဉ်းချုပ်အနေနဲ့ Maven က build လုပ်ငန်းစဉ်တွေကို အကောင်အထည်ဖော်ဖို့ plugins တွေကို အသုံးပြုပါတယ်။ Plugin တစ်ခုမှာ goals အနည်းဆုံးတစ်ခု သို့မဟုတ် အများကြီး ပါဝင်ပြီး၊ goal တစ်ခုချင်းစီက plugin ရဲ့ တာဝန်တစ်ခု ဖြစ်ပါတယ်။
Coordinates
Maven coordinates ဆိုတာက project တွေကို တိတိကျကျ ဖော်ပြဖို့အတွက် POM ဖိုင်ထဲမှာ သတ်မှတ်ထားတဲ့ အချက်လက်တွေပါ။ ဒီ coordinate တွေမှာ groupId, artifactId, version ဆိုပြီး သုံးခု ပါဝင်ပါတယ်။
groupId က project ကို တာဝန်ယူထားတဲ့ အဖွဲ့၊ ကုမ္ပဏီ၊ ဒါမှမဟုတ် ဌာနကို ပြပါတယ်။ ပုံမှန်အားဖြင့် domain name ကို နောက်ပြန်စဉ်ပြီး သုံးပါတယ်။ ဥပမာ ကျွန်တော်တို့ကုမ္ပဏီအတွက် groupId က io.datajek ဖြစ်နိုင်ပါတယ်။
artifactId က groupId အောက်မှာ project တစ်ခုချင်းစီအတွက် ထူးခြားတဲ့ နာမည်ဖြစ်ပြီး၊ တူညီတဲ့ groupId ရှိတဲ့ project တွေမှာ artifactId က မတူကြပါဘူး။
version က project ရဲ့ ထုတ်လုပ်မှု အဆင့်ကို ဖော်ပြတာဖြစ်ပြီး၊ quarterly အလိုက် update လုပ်တဲ့ library တစ်ခုမှာ version နံပါတ် မတူညီစွာ သတ်မှတ်ပေးပါတယ်။ ဒီ coordinate သုံးခုကြောင့် project တစ်ခုကို တိတိကျကျ သတ်မှတ်နိုင်ပြီး အခြား project တွေမှာ အလွယ်တကူ ရည်ညွှန်းနိုင်ပါတယ်။
ဒီ identifier သုံးခု (groupId, artifactId, version) တို့ရဲ့ ဆက်နွယ်မှုကို အောက်ပါအတိုင်း ဖော်ပြနိုင်ပါတယ်။ groupId က project ကို တာဝန်ယူထားတဲ့ အဖွဲ့ သို့မဟုတ် ကုမ္ပဏီကို ဖော်ပြပြီး၊ artifactId က အဲဒီ groupId အောက်မှာ project တစ်ခုချင်းစီအတွက် ထူးခြားတဲ့ နာမည်ဖြစ်ပါတယ်။ version ကတော့ အဲဒီ project ရဲ့ ထုတ်လုပ်မှု အဆင့် သို့မဟုတ် ဗားရှင်းကို ဖော်ပြပါတယ်။ ဒီသုံးခုကို တွဲဖက်ပြီး project တစ်ခုကို တိတိကျကျ သတ်မှတ်နိုင်ပါတယ်။

An example of the three values for a project is shown below:
<groupId>io.datajek</groupId>
<artifactId>maven-course</artifactId>
<version>1.0-SNAPSHOT</version>
Maven တွင် project တစ်ခုကို တိတိကျကျ သတ်မှတ်ဖို့ attribute သုံးခုရှိပါတယ်။ အဲဒီ attribute တွေကတော့ groupId, artifactId, version ဖြစ်ပြီး၊ ဒီ attribute သုံးခုလုံးတူတဲ့ project နှစ်ခု မရှိနိုင်ပါဘူး။ ဒါကြောင့် ဒီသုံးခုက project ကို တစ်ခုတည်းသာ သတ်မှတ်ပေးနိုင်ပါတယ်။
ဒါ့အပြင် Maven coordinates အနေနဲ့ packaging နဲ့ classifier ဆိုတဲ့ POM ဖိုင် attribute နှစ်ခုလည်း ပါဝင်ပါတယ်။ ဒါပေမယ့် ဒီနှစ်ခုက project ကို တိတိကျကျ သတ်မှတ်ရာမှာ မပါဝင်ပါဘူး။
packaging က project ရဲ့ အမျိုးအစားကို ဖော်ပြပါတယ်။ ဥပမာ packaging ကို jar သတ်မှတ်ထားရင် jar archive ထုတ်ပေးမယ်၊ war သတ်မှတ်ထားရင် web application ထုတ်ပေးမှာ ဖြစ်ပါတယ်။
classifier ကတော့ optional string တစ်ခုဖြစ်ပြီး၊ တူညီတဲ့ POM ကနေ content မတူတဲ့ artifact တွေကို ခွဲခြားဖော်ပြဖို့ အသုံးပြုပါတယ်။ ဥပမာ Java application တစ်ခုကို Java version 8 နဲ့ 11 နှစ်မျိုးအတွက် ထုတ်လုပ်မယ်ဆိုရင် classifier ကို jdk8 နဲ့ jdk11 လို့ သတ်မှတ်နိုင်ပြီး၊ အသုံးပြုသူတွေက သူတို့ Java version အလိုက် artifact ကို ရွေးချယ်နိုင်ပါတယ်။
Maven coordinates တွေကို colon (:) နဲ့ ခွဲပြီး အောက်ပါပုံစံအတိုင်း ဖော်ပြပါတယ်။
groupId:artifactId:packaging:version
ဥပမာအနေနဲ့ ကျွန်တော်တို့ project မှာတော့
io.datajek:maven-course:jar:1.0-SNAPSHOT
ဖြစ်ပါတယ်။ ဒီ coordinate တွေကို အသုံးပြုပြီး POM ဖိုင်ထဲမှာ project ရဲ့ dependency တွေကို ရိုးရှင်းစွာ ဖော်ပြနိုင်ပါတယ်။ နောက်ထပ် lessons တွေမှာတော့ dependency တွေကို ဘယ်လို သတ်မှတ်ရမယ်ဆိုတာကို လေ့လာသွားမှာ ဖြစ်ပါတယ်။
Repositories
Maven World and Project Storage
"Maven world" ဆိုတာက Apache Maven နဲ့ ပတ်သက်တဲ့ လုပ်ဆောင်မှုတွေနဲ့ ပတ်ဝန်းကျင်တစ်ခုလုံးကို ရည်ညွှန်းပါတယ်။ Apache Maven ကတော့ Java project တွေအတွက် အဓိကထားပြီး အသုံးပြုတဲ့ build automation နဲ့ project management tool တစ်ခု ဖြစ်ပါတယ်။
ဒီသင်ခန်းစာရဲ့ အခြေအနေအရ "Maven world" ဆိုတာက project တွေကို Maven coordinates တွေနဲ့ တိတိကျကျ ခွဲခြားသတ်မှတ်ပြီး၊ ပြန်လည်ရယူနိုင်ဖို့နဲ့ dependency တွေကို စီမံခန့်ခွဲဖို့အတွက် repositories (local နဲ့ remote) တွေမှာ သိမ်းဆည်းထားတဲ့ စနစ်တစ်ခုလို့ သတ်မှတ်နိုင်ပါတယ်။
Maven world မှာ project တွေကို တိတိကျကျ သတ်မှတ်နိုင်တယ်ဆိုတာ ကျွန်တော်တို့ သိထားပြီးပါပြီ။ ဒါပေမဲ့ ဒီ project တွေက ဘယ်မှာ ရှိနေတာလဲ။ တိတိကျကျ သတ်မှတ်ထားတာက ပြန်လည်ရယူလို့ မရနိုင်ဘူးဆိုရင် အကျိုးမရှိပါဘူး။
Repositories များ
Maven ecosystem မှာ project တွေကို repositories တွေမှာ သိမ်းဆည်းထားပါတယ်။ Repository ဆိုတာက Maven project တွေထုတ်လုပ်တဲ့ products တွေကို သိမ်းဆည်းရာနေရာ ဖြစ်ပါတယ်။ Repository အမျိုးအစား နှစ်မျိုးရှိပြီး၊ သူတို့ ဘယ်လို လုပ်ဆောင်ကြတယ်ဆိုတာ နားလည်ထားဖို့ အရေးကြီးပါတယ်။ အဲဒါတွေကတော့ Local Repository နဲ့ Remote Repository ပဲ ဖြစ်ပါတယ်။
Local Repository
Local Repository ကတော့ သင့် project အတွက် လိုအပ်တဲ့ artifacts တွေနဲ့ dependencies တွေကို local cache အနေနဲ့ အသုံးပြုပြီး၊ သင့် project က ထုတ်လုပ်တဲ့ artifacts တွေကိုလည်း သိမ်းဆည်းထားပါတယ်။ Local Repository ကို သင့်ကွန်ပျူတာပေါ်မှာ တည်ရှိပြီး၊ Maven command ကို ပထမဆုံး run တဲ့အချိန်မှာ ဖန်တီးပေးပါတယ်။ Maven က အစပိုင်းမှာ skeleton သာရှိပြီး၊ core plugins တွေကို remote repository ကနေ download လုပ်ပြီး local repository ထဲမှာ သိမ်းဆည်းထားတာ ဖြစ်ပါတယ်။

Location and Testing of Local Repository
ပုံမှန်အားဖြင့် Local Repository ကို Unix စနစ်များတွင် / <username>/.m2/repository သို့မဟုတ် ~/.m2/repository လမ်းကြောင်းမှာ ဖန်တီးပေးပါတယ်။ ကျွန်ုပ်တို့ရဲ့ local repository ထဲကို စမ်းသပ် project တစ်ခုကို အောက်ပါ လေ့ကျင့်ခန်းအတိုင်း ထည့်သွင်းကြည့်ပါမယ်။ အောက်က အဆင့်တွေကို လိုက်နာဆောင်ရွက်နိုင်ပါတယ်။
# .m2 directory ရှိမရှိ စစ်ဆေးခြင်း
ls ~/.m2/repository
# Maven command တစ်ခုခုကို run ပါ (မအောင်မြင်ရင်တောင် ရပါတယ်)
mvn
# .m2 directory ဖန်တီးပြီးသွားပေမယ့် ဗလာဖြစ်နေတာကို တွေ့ရပါလိမ့်မယ်
ls ~/.m2/repository
# Project တစ်ခုခုကို install လုပ်ပါ (Project1 ကို ဥပမာအနေနဲ့ သုံးပါမယ်)
cd /Project1
touch 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>io.datajek</groupId>
<artifactId>project1</artifactId>
<version>1</version>
<name>Project1</name>
<build>
<plugins>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>1</id>
<phase>pre-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo level="info">Learning Maven: pre-clean</echo>
</target>
</configuration>
</execution>
<execution>
<id>2</id>
<phase>post-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo level="info">Learning Maven: post-clean</echo>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
mvn install
# Local repository ထဲမှာ Maven က install လုပ်ထားတဲ့ artifact ကို စစ်ဆေးကြည့်ပါ
ls ~/.m2/repository/io/datajek/project1/1/
Maven က artifact တွေကို တခြားနေရာတွေမှာ ရှာဖွေခြင်းမပြုခင် Local Repository ထဲမှာ အမြဲတမ်း အရင်ရှာဖွေပါတယ် ဆိုတာကို မှတ်သားထားပါ။ Repository ဖွဲ့စည်းပုံကိုလည်း အာရုံစိုက်သင့်ပါတယ်။ အပေါ်က လေ့ကျင့်ခန်းမှာ ကျွန်တော်တို့ project ရဲ့ artifact ကို io/datajek/maven-course/ လမ်းကြောင်းမှာ install လုပ်ခဲ့ပါတယ်။ ယေဘုယျအားဖြင့် artifacts တွေကို repository ရဲ့ root နဲ့ ဆက်စပ်ပြီး အောက်ပါ format အတိုင်း လမ်းကြောင်းမှာ install လုပ်ပါတယ်။
<groupId>/<artifactId>/<version>/<artifactId>-<version>.<packaging>
Remote Repository (Central Repository)
အရင် ဥပမာမှာ ကျွန်တော်တို့ local repository နဲ့ လုပ်ဆောင်ခဲ့ပါတယ်။ Maven က အစပိုင်းမှာ core plugins တွေနဲ့ dependencies တွေကို Remote Repository ကနေ download လုပ်ပါတယ်။ ဒီ remote repository ရဲ့ တည်နေရာကို Maven မှာ ကြိုတင် configure လုပ်ထားပြီး https://repo1.maven.org/maven2/ လို့ သတ်မှတ်ထားပါတယ်။ ဒါကို Central Repository လို့ ခေါ်ပါတယ်။ တကယ်တော့ ဒီ URL ကို ဝင်ရောက်ကြည့်ရှုပြီး အထဲက directory တွေကို စစ်ဆေးကြည့်နိုင်ပါတယ်။ ဥပမာအနေနဲ့ အောက်ပါ Google jar artifact ကို ကျပန်း ရွေးချယ်ကြည့်ပါမယ်။
https://repo1.maven.org/maven2/com/google/apis/google-api-services-admob/v1-rev10-1.18.0-rc/
ဒီနေရာမှာ groupId က com.google.apis ဖြစ်ပြီး၊ artifactId က google-api-services-admob၊ version က v1-rev10-1.18.0-rc ဖြစ်ပါတယ်။ အပေါ်က URL ကို ဝင်ကြည့်မယ်ဆိုရင် download လုပ်လို့ရတဲ့ jar artifacts တွေကို တွေ့ရပါလိမ့်မယ်။
ဒီနေရာမှာ repository က လူအများလက်လှမ်းမီတဲ့အတွက် artifacts တွေကို ဘယ်သူမဆို download လုပ်နိုင်တယ်ဆိုတာ သတိပြုပါ။ ဒါပေမဲ့ အဖွဲ့အစည်းတိုင်းက သူတို့ရဲ့ code တွေကို အများပြည်သူသိအောင် ဖြန့်ဝေချင်တာမျိုး ဒါမှမဟုတ် developer တွေက အများပြည်သူသုံး repository ကနေ artifacts တွေ download လုပ်တာမျိုးကို မလိုလားပါဘူး။ ဒီလိုအခြေအနေမျိုးမှာ အဖွဲ့အစည်းတွေက သူတို့ရဲ့ ကိုယ်ပိုင် repository ကို ထူထောင်လေ့ရှိပါတယ်။ ဒါက Maven ရဲ့ public repository ကို မှန် (mirror) အဖြစ် ထားရှိတာမျိုး ဖြစ်နိုင်ပြီး၊ အဖွဲ့အစည်းရဲ့ network အတွင်းမှာပဲ လက်လှမ်းမီနိုင်ပါတယ်။ remote repository ရဲ့ တည်နေရာကို .m2 directory အောက်က settings.xml file ထဲမှာ configure လုပ်နိုင်ပါတယ်။

Life-cycle and Phases
Build Lifecycle
Maven မှာ build lifecycle ဆိုတဲ့ concept တစ်ခု ရှိပါတယ်။ ဒါကို ခြုံငုံပြီး ပြောရရင် Maven က project တစ်ခု ဒါမှမဟုတ် artifact တစ်ခုကို တည်ဆောက်ပြီး ဖြန့်ဝေဖို့အတွက် လုပ်ဆောင်တဲ့ an ordered set of actions လို့ သတ်မှတ်နိုင်ပါတယ်။
Build lifecycle တစ်ခုမှာ build phases တွေ ပါဝင်ပါတယ်။ phase တစ်ခုစီမှာ plugin goals တွေ ချိတ်ဆက်ထားပါတယ်။ lifecycle ရဲ့ တစ်စိတ်တစ်ပိုင်းအနေနဲ့ phase တစ်ခုကို run တဲ့အခါ အဲ့ဒီ plugin goals တွေလည်း အလိုအလျောက် အလုပ်လုပ်ပါတယ်။

ဥပမာ ကြည့်ရအောင်။ lifecycle တွေထဲက တစ်ခုကတော့ clean lifecycle ဖြစ်ပြီး၊ အောက်ပါ phases တွေ ပါဝင်ပါတယ်။
pre-clean
clean (ဒီ phase နာမည်နဲ့ lifecycle နာမည် clean က တစ်ခုတည်းမဟုတ်ဘူးဆိုတာ သတိပြုပါ)
post-clean
lifecycle ရဲ့ phases တွေဟာ အမြဲတမ်း အစီအစဥ်အတိုင်း အလုပ်လုပ်ပါတယ်၊ ဆိုလိုတာက pre-clean က အရင်ဆုံး၊ ပြီးရင် clean၊ နောက်ဆုံးမှ post-clean ဖြစ်ပါတယ်။ phase တစ်ခုစီအတွင်းမှာ အဲ့ဒီ phase နဲ့ ချိတ်ဆက်ထားတဲ့ plugin goals တွေ အလုပ်လုပ်ပါတယ်။ plugin goals တွေ ချိတ်ဆက်မထားတဲ့ build phase ကတော့ အလုပ်လုပ်မှာ မဟုတ်ပါဘူး။
လေ့ကျင့်ခန်းအနေနဲ့ EmptyProject ထဲမှာ clean lifecycle ရဲ့ clean phase ကို mvn clean command နဲ့ run ကြည့်ရအောင်။ mvn command နဲ့အတူ phase ကိုပါ ထည့်သွင်းသတ်မှတ်ထားတာကို သတိပြုပါ။ ကျွန်တော်တို့ clean phase ကို run တဲ့အခါ၊ အဲ့ဒီ phase ရဲ့ အရင် phase ဖြစ်တဲ့ pre-clean ကလည်း plugin goals တွေ ချိတ်ဆက်ထားရင် အလုပ်လုပ်သွားပါလိမ့်မယ်။


# Change directory to Empty Project
cd /EmptyProject
vi pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>io.datajek</groupId>
<artifactId>empty-project</artifactId>
<version>1</version>
<name>EmptyProject</name>
</project>
# Run mvn clean
mvn clean
EmptyProject directory ထဲမှာ mvn clean command ကို run လိုက်တဲ့အခါ အောက်ပါရလဒ်ကို တွေ့ရပါလိမ့်မယ်။

mvn clean command ရဲ့ output ကို ကြည့်ရင် clean lifecycle ရဲ့ clean build phase မှာ maven-clean-plugin ရဲ့ clean goal ကို လုပ်ဆောင်နေတာကို တွေ့ရပါလိမ့်မယ်။
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ empty-project ---
ဒီနေရာမှာ သတိပြုရမှာက ကျွန်တော်တို့ clean build phase ကို ခေါ်လိုက်ပေမယ့်၊ သူ့ရဲ့ အရင် phase ဖြစ်တဲ့ pre-clean ကတော့ အလုပ်မလုပ်ပါဘူး။ ဒါက ဘာကြောင့်လဲဆိုတော့ plugin goals တွေ ချိတ်ဆက်မထားတဲ့ build phase က အလုပ်မလုပ်ပါဘူး။
pre-clean phase ကို အလုပ်လုပ်စေရန် ပြင်ဆင်ခြင်း
pre-clean phase ကိုပါ အလုပ်လုပ်စေချင်တယ်ဆိုရင် ကျွန်တော်တို့ရဲ့ POM (Project Object Model) file ထဲမှာ အောက်ပါ code snippet ကို current pom.xml file တွင် ထည့်သွင်းပေးနိုင်ပါတယ်။
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>pre-clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Final:
<?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>io.datajek</groupId>
<artifactId>empty-project</artifactId>
<version>1</version>
<name>EmptyProject</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>pre-clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
အထက်ပါ ပြောင်းလဲမှုတွေက maven-clean-plugin ရဲ့ clean goal ကို pre-clean build phase နဲ့ ချိတ်ဆက်လိုက်တာ ဖြစ်ပါတယ်။ အခု mvn clean ကို ပြန် run ကြည့်မယ်ဆိုရင် အောက်မှာ ပြထားတဲ့အတိုင်း clean goal က နှစ်ကြိမ် အလုပ်လုပ်နေတာကို တွေ့ရပါလိမ့်မယ်။
mvn clean

Plugin Goals များကို Phase များနှင့် ချိတ်ဆက်ခြင်း
ကျွန်ုပ်တို့ဟာ plugin goals တွေကို build phases တွေနဲ့ ဘယ်လို ချိတ်ဆက်ရမယ်ဆိုတာကို နောက်ပိုင်းမှာ အသေးစိတ် လေ့လာသွားမှာပါ။ ဒါပေမဲ့ အခုလောလောဆယ်မှာ plugin goals တွေကို build phases တွေနဲ့ ချိတ်ဆက်လို့ရတယ်ဆိုတာ သိထားဖို့ လုံလောက်ပါတယ်။ နောက်ထပ် အရေးကြီးတဲ့ အချက်တစ်ခုကတော့ plugin goal တစ်ခုကို build phases တစ်ခုထက်ပိုပြီး ချိတ်ဆက်လို့ရတယ်ဆိုတာပဲ ဖြစ်ပါတယ်။ အပေါ်က လေ့ကျင့်ခန်းမှာ ကျွန်တော်တို့ မြင်ခဲ့ရတဲ့အတိုင်းပါပဲ။

ဒါဆိုရင် clean goal က ဘာအတိအကျလုပ်ဆောင်တာလဲလို့ မေးကောင်းမေးလာနိုင်ပါတယ်။ clean plugin ရဲ့ အသေးစိတ်အချက်အလက်တွေကို https://maven.apache.org/plugins/maven-clean-plugin/ ရှာဖွေနိုင်ပါတယ်။ တကယ်တော့ ဘယ်သူမဆို တခြားသူတွေ အသုံးပြုနိုင်တဲ့ plugin တစ်ခုကို ရေးသားနိုင်ပါတယ်။ clean plugin မှာ clean ဆိုတဲ့ goal တစ်ခုတည်းသာ ရှိပြီး၊ ဒီ goal က project ရဲ့ working directory ထဲမှာ build လုပ်နေစဉ်အတွင်း ထုတ်လုပ်လိုက်တဲ့ artifacts တွေကို ဖျက်ပစ်ပါတယ်။
pre-clean Phase တွင် စိတ်ဝင်စားစရာများ ထပ်ထည့်ခြင်း
pre-clean phase မှာ ပိုပြီး စိတ်ဝင်စားစရာကောင်းတဲ့ အရာတစ်ခုကို လုပ်ဆောင်နိုင်ပါတယ်။ maven-antrun-plugin ရဲ့ run goal ကို pre-clean phase နဲ့ ချိတ်ဆက်ပြီး စာသားမက်ဆေ့ချ်တစ်ခုကို ပြသနိုင်ပါတယ်။ ဒီ plugin ကို Maven build ထဲမှာ Ant tasks တွေ လုပ်ဆောင်ဖို့ အသုံးပြုပါတယ်။ Ant ဆိုတာက Maven ထက် အရင်ပေါ်ခဲ့တဲ့ build tool တစ်ခုဖြစ်ပြီး tasks ဆိုတဲ့ သဘောတရား ရှိပါတယ်။ tasks တွေထဲက တစ်ခုကတော့ echo ဖြစ်ပြီး console ပေါ်မှာ မက်ဆေ့ချ်တစ်ခုကို ပြသတာ ဖြစ်လို့ ကျွန်တော်တို့ ဒါကို အသုံးပြုပါမယ်။ ဒီ plugin နဲ့ ပတ်သက်တဲ့ အသေးစိတ် အချက်အလက်တွေကို https://maven.apache.org/plugins/maven-antrun-plugin/ ရှာဖွေနိုင်ပါတယ်။ လိုအပ်တဲ့ plugin snippet ကို POM file ထဲမှာ အောက်ပါအတိုင်း ဖော်ပြထားပါတယ်။
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>1</id>
<phase>pre-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo level="info">Learning Maven: pre-clean</echo>
</target>
</configuration>
</execution>
<execution>
<id>2</id>
<phase>post-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo level="info">Learning Maven: post-clean</echo>
</target>
</configuration>
</execution>
</executions>
</plugin>
Final:
<?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>io.datajek</groupId>
<artifactId>empty-project</artifactId>
<version>1</version>
<name>EmptyProject</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>1</id>
<phase>pre-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo level="info">Learning Maven: pre-clean</echo>
</target>
</configuration>
</execution>
<execution>
<id>2</id>
<phase>post-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo level="info">Learning Maven: post-clean</echo>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
အထက်ပါ snippet က clean lifecycle ရဲ့ pre-clean ဒါမှမဟုတ် post-clean build phase အလုပ်လုပ်တဲ့အခါ၊ ပေးထားတဲ့ configuration နဲ့အတူ maven-antrun-plugin ရဲ့ run goal ကို အလုပ်လုပ်စေမယ်လို့ ဖော်ပြထားပါတယ်။ အောက်ပါ လေ့ကျင့်ခန်းမှာ clean lifecycle ရဲ့ pre-clean နဲ့ post-clean build phases နှစ်ခုလုံးနဲ့ run goal ကို ချိတ်ဆက်ထားတဲ့ project တစ်ခုကို တည်ဆောက်ပါမယ်။ ပထမဆုံး mvn clean ကို run ပြီးတော့ mvn post-clean ကို run ကာ ရလဒ်တွေကို လေ့လာကြည့်ပါမယ်။
# cd to Project 1 directory
cd /Project1
# Examine the pom.xml file
cat pom.xml
# Now run mvn clean and see the message print on console
# only once since the post-clean phase doesn't execute
mvn clean
# Now run post-clean and observe two messages being printed
# on the console.
mvn post-clean


အပေါ်က လေ့ကျင့်ခန်းအတိုင်း လုပ်ဆောင်ပြီးနောက် output ကို ကြည့်မယ်ဆိုရင် “Learning Maven: pre-clean” ဆိုတဲ့ စာသားနဲ့ “Learning Maven: post-clean” ဆိုတဲ့ စာသားတွေ ပေါ်လာတာကို တွေ့ရပါလိမ့်မယ်။ ဒါက pre-clean, clean, နဲ့ post-clean phases တွေအားလုံး အလုပ်လုပ်ခဲ့တယ်ဆိုတာကို ပြသနေတာ ဖြစ်ပါတယ်။
ဒါပေမဲ့ ကျွန်တော်တို့ mvn clean command ကိုပဲ run လိုက်မယ်ဆိုရင်တော့ ဒုတိယ message (i.e., “Learning Maven: post-clean”) က console ပေါ်မှာ ပေါ်လာမှာ မဟုတ်ပါဘူး။ ဘာလို့လဲဆိုတော့ post-clean phase က အလုပ်လုပ်မှာ မဟုတ်လို့ပါပဲ။
Lifecycle များအကြောင်း ဆက်လက်လေ့လာခြင်း
ဒီသင်ခန်းစာမှာ Maven ရဲ့ အခြားသော lifecycle တွေဖြစ်တဲ့ Default နဲ့ Site lifecycle တွေအကြောင်းကို ဆက်လက်ဆွေးနွေးသွားမှာ ဖြစ်ပါတယ်။
Clean lifecycle မှာ phases သုံးခုသာ ပါဝင်ပြီး နားလည်ရလွယ်ကူတာကြောင့် အရင်သင်ခန်းစာမှာ အသုံးပြုခဲ့ပါတယ်။ lifecycle တွေအားလုံးကို online reference မှာ ကြည့်ရှုနိုင်ပါတယ်။ အခု ကျွန်တော်တို့ အများဆုံး အသုံးပြုကြတဲ့ Default Lifecycle ကို ရှင်းပြပါမယ်။ ဒါ့အပြင် အောက်ပါ phases တွေ ပါဝင်ပါတယ်။
validateinitializegenerate-sourcesprocess-sourcesgenerate-resourcesprocess-resourcescompileprocess-classesgenerate-test-sourcesprocess-test-sourcesgenerate-test-resourcesprocess-test-resourcestest-compileprocess-test-classestestprepare-packagepackagepre-integration-testintegration-testpost-integration-testverifyinstalldeploy
lifecycle တစ်ခုမှာ ဘယ် phase တွေ ပါဝင်တယ်ဆိုတာ ဘယ်သူက ဆုံးဖြတ်သလဲလို့ သင် သိချင်နိုင်ပါတယ်။ ဒီအချက်အလက်ကို maven-core codebase ရဲ့ components file မှာ သတ်မှတ်ထားပါတယ်။ Default lifecycle နဲ့ တခြား lifecycle တွေရဲ့ ကွာခြားချက်ကတော့ default lifecycle ထဲက phases တွေဟာ project ရဲ့ packaging ပုံစံပေါ် မူတည်ပြီး မတူညီတဲ့ plugin goals တွေနဲ့ ချိတ်ဆက်ထားတာပဲ ဖြစ်ပါတယ်။ Site နဲ့ clean lifecycle နှစ်ခုလုံးက သူတို့ရဲ့ phases တွေကို plugin goals တွေနဲ့ သတ်မှတ်ထားပြီးသား ဖြစ်ပါတယ်။ default lifecycle ရဲ့ မတူညီတဲ့ phases တွေအတွက် ချိတ်ဆက်မှုတွေကို ဒီနေရာမှာ ကြည့်နိုင်ပါတယ်။ ဥပမာ - packaging ကို jar လို့ သတ်မှတ်ထားရင် compile phase က default directory ဖြစ်တဲ့ /src/main/java/ အောက်က Java files တွေကို ရှာဖွေပြီး compile လုပ်ဖို့ ကြိုးစားပါလိမ့်မယ်။
ဒါပေမဲ့ packaging ကို pom လို့ ပြောင်းလိုက်တဲ့အခါ compile phase က ဘာမှ လုပ်ဆောင်မှာ မဟုတ်ပါဘူး။ ဘာလို့လဲဆိုတော့ pom packaging အတွက် compile phase မှာ plugin goal ချိတ်ဆက်ထားတာ မရှိလို့ပဲ ဖြစ်ပါတယ်။
ဒီသဘောတရားတွေကို ပိုမိုနားလည်နိုင်ဖို့ အောက်ပါ လေ့ကျင့်ခန်းကို လုပ်ဆောင်ကြည့်ရအောင်။
# Create a directory named Project2
mkdir Project2
# Change directory to Project 2
cd Project2
# Create a pom.xml file
touch pom.xml
# with packaging set to pom
<packaging>pom</packaging>
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>io.datajek</groupId>
<artifactId>empty-project</artifactId>
<version>1</version>
<name>Project2</name>
<packaging>pom</packaging>
</project>
# Run mvn install. Take note of phases in default life-cycle that run
mvn install

pom packaging နဲ့ဆိုရင် default lifecycle ကနေ အောက်ပါ phases တွေကို လုပ်ဆောင်တာကို တွေ့ရပါလိမ့်မယ်။
maven-install-pluginရဲ့installgoal ဟာinstallphase မှာ အလုပ်လုပ်ပါတယ်။
# Now open the pom file in vim and change <packaging>pom</packaging> to
# <packaging>jar</packaging>.
vi pom.xml
# Now again mvn install and notice the phases of the default life-cycle that run.
mvn install

packaging ကို jar ကို ပြောင်းလိုက်တဲ့အခါ အောက်ပါ phases တွေ အစီအစဥ်အတိုင်း အလုပ်လုပ်ပါတယ်။
maven-resources-pluginရဲ့resourcesgoal ဟာprocess-resourcesphase မှာ အလုပ်လုပ်ပါတယ်။maven-compiler-pluginရဲ့compilegoal ဟာcompilephase မှာ အလုပ်လုပ်ပါတယ်။maven-resources-pluginရဲ့testResourcesgoal ဟာprocess-test-resourcesphase မှာ အလုပ်လုပ်ပါတယ်။maven-compiler-pluginရဲ့testCompilegoal ဟာtest-compilephase မှာ အလုပ်လုပ်ပါတယ်။maven-surefire-pluginရဲ့testgoal ဟာtestphase မှာ အလုပ်လုပ်ပါတယ်။maven-jar-pluginရဲ့jargoal ဟာpackagephase မှာ အလုပ်လုပ်ပါတယ်။maven-install-pluginရဲ့installgoal ဟာinstallphase မှာ အလုပ်လုပ်ပါတယ်။
Default lifecycle မှာ အပေါ်က phases ခုနစ်ခုပဲ အလုပ်လုပ်တာကို သတိပြုပါ။ ဘာလို့လဲဆိုတော့ သူတို့မှာ goals တွေ ချိတ်ဆက်ထားလို့ပဲ ဖြစ်ပါတယ်။ default lifecycle ထဲက တခြား phases တွေကတော့ default အနေနဲ့ plugin goals တွေ ချိတ်ဆက်ထားတာမရှိတဲ့အတွက် အလုပ်မလုပ်ပါဘူး။ default lifecycle ရဲ့ မတူညီတဲ့ packaging တွေအတွက် plugin bindings တွေကို https://maven.apache.org/ref/3.6.3/maven-core/default-bindings.html ရှာဖွေနိုင်ပါတယ်။
Site Lifecycle
Site lifecycle မှာ အောက်ပါ phases တွေ ပါဝင်ပေမယ့် site နဲ့ site-deploy phases တွေမှာပဲ default အနေနဲ့ plugin goals တွေ ချိတ်ဆက်ထားပါတယ်။
pre-sitesitepost-sitesite-deploy
ဒါကြောင့် mvn pre-site ဒါမှမဟုတ် mvn post-site ကို run လိုက်မယ်ဆိုရင် plugin goal တစ်ခုမှ အလုပ်လုပ်မှာ မဟုတ်ဘဲ project အတွက် ဘာမှ ပြောင်းလဲမှု ရှိလာမှာ မဟုတ်ပါဘူး။
Site lifecycle ကို ဘယ်အချိန်မှာ အသုံးပြုလဲဆိုတော့ project ရဲ့ documentation (စာရွက်စာတမ်းများ) ဒါမှမဟုတ် reports (အစီရင်ခံစာများ) တွေကို ထုတ်လုပ်ပြီး deploy (ဖြန့်ချီ) ချင်တဲ့အခါမှာ အသုံးပြုပါတယ်။
ဥပမာအားဖြင့်၊ သင်ဟာ project တစ်ခုအတွက် website တစ်ခု ဖန်တီးချင်တယ်ဆိုပါစို့။ အဲ့ဒီ website ထဲမှာ reports တွေ၊ project ရဲ့ အသေးစိတ်အချက်အလက်တွေနဲ့ တခြား စာရွက်စာတမ်းတွေလိုမျိုး အချက်အလက်တွေကို ထည့်သွင်းပြီးရင်၊ အဲ့ဒီ site ကို server တစ်ခု ဒါမှမဟုတ် repository တစ်ခုဆီကို deploy လုပ်ဖို့အတွက် site lifecycle ကို အသုံးပြုနိုင်ပါတယ်။
POM (Project Object Model)
ဒီသင်ခန်းစာက POM file ရဲ့ ရည်ရွယ်ချက်နဲ့ ဖွဲ့စည်းပုံကို ရှင်းပြထားပါတယ်။
Maven project တစ်ခုကို POM file တစ်ခုနဲ့ ဖော်ပြထားပါတယ်။ POM ဆိုတာ Project Object Model ရဲ့ အတိုကောက်ဖြစ်ပြီး project ရဲ့ declarative description တစ်ခု ဖြစ်ပါတယ်။ ဒါက project ရဲ့ ထူးခြားတဲ့ Maven coordinates တွေ၊ project ရဲ့ dependencies တွေ၊ လိုအပ်တဲ့ plugins တွေ၊ Maven က project ရဲ့ အခြေအနေအရ အလုပ်လုပ်မယ့် goals တွေအတွက် လိုအပ်တဲ့ parameters တွေ စတာတွေကို သတ်မှတ်ပေးပါတယ်။ ဒါဟာ project နဲ့ပတ်သက်တဲ့ အချက်အလက်တွေနဲ့ Maven က project ကို build လုပ်ဖို့ အသုံးပြုတဲ့ configuration details တွေ ပါဝင်တဲ့ XML file တစ်ခု ဖြစ်ပါတယ်။ Maven ကို အလုပ်လုပ်ခိုင်းတဲ့အခါ (invoked လုပ်တဲ့အခါ) POM file ကို ရှာဖွေပြီး အဲ့ဒီ file ထဲက အချက်အလက်တွေအတိုင်း လုပ်ဆောင်ပါတယ်။ POM file မရှိဘူးဆိုရင် Maven က error ပြပါလိမ့်မယ်။ task ဒါမှမဟုတ် goal တစ်ခုကို အလုပ်လုပ်တဲ့အခါ Maven က လက်ရှိ directory မှာ POM ကို ရှာဖွေပါတယ်။ ပြီးရင် POM ကို ဖတ်ပြီး လိုအပ်တဲ့ configuration အချက်အလက်တွေကို ရယူကာ goal ကို လုပ်ဆောင်ပါတယ်။
POM မှာ သတ်မှတ်နိုင်တဲ့ configuration တွေထဲက တချို့ကတော့ project dependencies တွေ၊ လုပ်ဆောင်နိုင်တဲ့ plugins ဒါမှမဟုတ် goals တွေ၊ build profiles တွေ စတာတွေ ဖြစ်ပါတယ်။ project version၊ description၊ developers၊ mailing lists စတဲ့ တခြားအချက်အလက်တွေကိုလည်း သတ်မှတ်နိုင်ပါတယ်။
အောက်မှာတော့ အနည်းဆုံး အချက်အလက်တွေ ပါဝင်တဲ့ POM file တစ်ခုကို ဖော်ပြထားပါတယ်။
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>io.datajek</groupId>
<artifactId>empty-project</artifactId>
<version>1</version>
</project>
ဒီ file မှာ project ရဲ့ အနည်းဆုံး ဖော်ပြချက်တွေပဲ ပါဝင်ပါတယ်။ dependencies ဒါမှမဟုတ် plugins တွေ ဘာတစ်ခုမှ သတ်မှတ်ထားခြင်း မရှိပါဘူး။ အထက်ပါ POM file ပါဝင်တဲ့ directory ထဲမှာ mvn install command ကို run လိုက်မယ်ဆိုရင် build အောင်မြင်တာကို တွေ့ရပါလိမ့်မယ်။ အောက်က terminal မှာ စမ်းကြည့်ရအောင်။
# Notice the local repository doesn't exist initially.
ls ~/.m2
# Change directory to the empty project which has the minimal POM file.
cd /EmptyProject
# Invoke mvn package (not install).
mvn package
# Running mvn package would run default goals for various Maven
# phases and produce a empty-project-1.jar file in the target directory.
# Examine the jar produced, which may seem counterintuitive given the fact
# that we have no source code files as yet.
ls target/
# You can verify the jar has no classes.
jar -tf target/empty-project-1.jar
# Verify local repository doesn't have empty-project-1.jar installed
ls ~/.m2/repository/io/datajek/
# Now we'll run a different maven phase install.
mvn install
# Notice that the repository now has the jar installed
ls ~/.m2/repository/io/datajek/empty-project/1/

Maven ရဲ့ Default Settings နဲ့ POM ဖိုင်၏ အရေးပါပုံ
ကျွန်တော်တို့ Java code ဖိုင်တွေ ထည့်မထားပေမယ့်လည်း Maven က default settings တွေကို ရယူပြီး jar artifact တစ်ခုကို ထုတ်ပေးတာကို သတိပြုမိပါလိမ့်မယ်။ ဒါဟာ Maven က developer ရဲ့ ဝန်ထုပ်ဝန်ပိုးကို လျှော့ချပေးပြီး သင့်လျော်တဲ့ default တွေကို သူ့ဘာသာသူ ရွေးချယ်ပေးပုံ ဥပမာတစ်ခု ဖြစ်ပါတယ်။ နောက်ထပ် အရေးကြီးတဲ့ အချက်တစ်ခုကတော့ Maven က jar artifact ကို local repository ထဲမှာ ထည့်သွင်းတဲ့အခါ အောက်ကပုံမှာ ပြထားတဲ့အတိုင်း အဲ့ဒီ jar အတွက် POM file ကိုပါ တစ်ပါတည်း ထည့်ပေးပါတယ်။

Dependency Management အကြောင်း လေ့လာတဲ့အခါ POM file ကို repository မှာ ဘာကြောင့် ထည့်ထားလဲဆိုတာကို သိလာပါလိမ့်မယ်။
POM က XML file တစ်ခုဖြစ်ပြီး XML file တစ်ခုရဲ့ schema ကို သက်ဆိုင်ရာ XSD file (XML Schema Definition ရဲ့ အတိုကောက်) က ထိန်းချုပ်ထားပါတယ်။ XSD file တစ်ခုက Extensible Markup Language (XML) document ထဲမှာပါတဲ့ elements တွေကို ပုံမှန်အတိုင်း ဖော်ပြပေးပါတယ်။ Maven အတွက် POM file ရဲ့ ဖွဲ့စည်းပုံကို XSD file တစ်ခုက ဖော်ပြပြီး POM file ထဲက <modelVersion> element ကနေ ကိုယ်စားပြုပါတယ်။ ကျွန်တော်တို့ <modelVersion> element ကို 4.0.0 ဆိုတဲ့ value ပေးထားပါတယ်။
တရားဝင် documentation ကနေ ကိုးကားရရင်- <modelVersion> element က ဒီ POM က ဘယ် object model version ကို အသုံးပြုနေတယ်ဆိုတာကို ပြသပါတယ်။ model ရဲ့ version က အလွန်အမင်း မကြာခဏ ပြောင်းလဲလေ့မရှိပေမယ့် Maven developer တွေက model ကို ပြောင်းလဲဖို့ လိုအပ်တယ်လို့ ယူဆတဲ့အခါ အသုံးပြုမှု တည်ငြိမ်စေဖို့အတွက် မဖြစ်မနေ ထည့်သွင်းရတာ ဖြစ်ပါတယ်။ Model ဆိုတာက POM file ရဲ့ ဖွဲ့စည်းပုံကို ရည်ညွှန်းတာ ဖြစ်ပါတယ် (ဥပမာ- ဘယ် element တွေကို ခွင့်ပြုလဲ၊ ဘယ် element တွေက မဖြစ်မနေထည့်ရမလဲ၊ ဒါမှမဟုတ် သူတို့ကို ဘယ်လို အဓိပ္ပာယ်ဖွင့်ဆိုမလဲ စသည်ဖြင့်)။ XSD ကို ဒီနေရာမှာ ရှာဖွေနိုင်ပြီး လွယ်ကူစွာ ကိုးကားနိုင်ဖို့ အောက်က widget မှာ ပြန်လည် ဖော်ပြထားပါတယ်။ POM ထဲမှာ သင်မြင်ရတဲ့ XML element တိုင်းကို အောက်က XSD ထဲမှာ သတ်မှတ်ထားတာကို တွေ့ရပါလိမ့်မယ်။