Maven ใช้งาน part 1 — สร้างโปรเจกต์

Phai Panda
4 min readJul 7, 2020

--

สำหรับ build tool คงไม่มีจาวาโปรแกรมเมอร์คนไหนที่ไม่รู้จัก Maven ก่อนที่ยุคนี้ใครหลายคนหันไปใช้ Gradle มือเก่ามือเก๋าทั้งหลายก็ยังคงเลือกใช้ Maven มันเพราะอะไรกันนะ?

ผมเป็นคนหนึ่งที่เคยเขียนงานจาวาแบบไม่ใช้ build tool ผลคือผมจะหา .jar เก่งมาก เพื่อที่จะประกอบร่างโปรเจกต์จึงเข้าใจคำว่า dependency อย่างยิ่ง

Dependency คืออะไรล่ะ?

พูดในฐานะมือใหม่ด้วยกัน ภาษาชาวบ้านด้วย ง่ายๆ dependency เสมือนสามีกับภรรยา เป็นสามีที่มีภรรยาน้อยได้หลายคน เป็นภรรยาที่มีชู้ได้หลายคน และเขาทั้งหมดเหล่านั้นต้องอยู่บ้านเดียวกันให้ได้อย่างปกติสุข

แล้วถ้าไม่ปกติสุขล่ะ? ก็บ้านแตกไง โปรเจกต์พัง

โปรเจกต์นั้นเสมือนบ้านหลังหนึ่ง แล้วประดา .jar ทั้งหลายก็คือคู่สามีภรรยาน้อยและชู้อยู่ร่วมกัน ช้าก่อนนะ อย่าเพิ่งไปคิดว่านี่มันเรื่องบ้าบออะไร เปรียบเปรยเลอะเทอะ ผมแค่อยากสื่อให้เพื่อนๆจำได้ เมื่อทราบแนวคิด (concept) คือบรรลุเป้าหมายแล้วก็ผ่านไปครับ

คนคนหนึ่งสร้าง .jar ขึ้นมาแล้วแจกจ่าย อีกหลายคนก็หยิบ .jar นั้นมาใช้งาน มากเข้าก็จะพบว่าเวอร์ชันต่างๆที่ทยอยออกมากลับพากัน error เนื่องจากเวอร์ชันไม่เข้ากัน คลาสที่เคยเรียกได้หายไปแล้ว หรือ interface ต่างๆเปลี่ยนแปลงไป มันจึงสำคัญมากที่จะเกิดการตั้งคำถามว่า ฉันจะจัดการกับความไม่เข้ากันให้เข้ากันได้อย่างไร ฉันจะรู้ได้อย่างไรว่าแต่ละ .jar ต้องการ .jar ตัวไหนอีกบ้าง ฉันต้องตามหาจาก error ที่ปรากฏไปเรื่อยๆ ฉันมาถูกทางไหม?

คำตอบคือ ตราบใดที่นำ .jar มาทำงานร่วมกันแล้วบ้านไม่แตกโปรเจกต์ไม่พังก็ถูกทางแล้วครับ แต่จะดีกว่านี้มากหากว่ามีผู้จัดการสิ่งเหล่านี้ให้เรา

ผู้จัดการ dependency ของประดา .jar มีหลายจ้าว เขาเรียกตัวเองว่า build tool จ้าวดังๆ เช่น

โปรเจกต์ที่เขียนด้วยภาษาจาวาจึงมักสร้างจาก build tool ข้างต้นและในบทความนี้ผมจะมาเล่าเรื่องการใช้งาน Apache Maven หรือสั้นๆว่า Maven ครับ

ว่าด้วยการใช้งาน Maven

ผมรู้ๆ ว่ามันน่าเบื่อแค่ไหนเวลามาต้องมาเรียนทฤษฎี ทุกคนจึงอยากได้ตัวอย่างไม่ก็โค้ดแนวทางแบบคัดลอกวางแล้วได้งานเลย แน่นอนผมก็เหมือนกัน

แต่นี่เป็นบทความเรียนรู้นะมีทฤษฎีหน่อยคงไม่เป็นไร (ใช่ไหม)

ผมจะนำการเขียนงานจาวาด้วยการสร้างโปเจกต์ที่ใช้ Maven เป็น build tool เริ่มจากสร้าง folder เปล่าๆเป็นชื่อโปรเจกต์ แล้วจัดโครงสร้างให้เป็นแบบที่ Maven ชอบ วาง pom.xml ลงไปแล้ว ปัง! ได้ .jar พร้อมนำไปทำงาน

เครื่องมือ

โครงสร้างของโปรเจกต์ Maven

https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html

ชื่อโปรเจกต์คือ hello

create folder
folder name hello

จากนั้น open folder นี้ด้วย VS Code

จากภาพโครงสร้างของโปรเจกต์ Maven จะต้องประกอบด้วย folder ย่อยเข้าไปดังนี้ src > main > java

โปรดสังเกตว่าจะเลือก folder ไหนก็ให้กดที่ชื่อ folder นั้นๆ

create sub folders

จากนั้นเป็นชื่อ package ซึ่งจะตั้งเป็น com.example.pros ก็สร้างย่อยเข้าไปอีก

create package folders

สร้างคลาสหลักชื่อ Main.java มีเนื้อหาเป็นเมธอด main

create Main.java & main method
public class Main {  public static void main(String[] args) {    System.out.println("Hello");  }}

เพื่อนๆจะสังเกตว่าชื่อ package นั้นไม่ถูกต้อง เนื่องจากตัว VS Code สร้างให้เอง มันยังไม่รู้ว่านี่เป็นโปรเจกต์จาวาที่กำลังจะใช้ build tool

ต่อไปให้สร้างไฟล์ที่เรียกว่า Project Object Model (POM) ชื่อ pom.xml ไว้ถัดจาก folder ของโปรเจกต์

create pom.xml
<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.pros</groupId>  <artifactId>hello</artifactId>  <version>1.0-SNAPSHOT</version></project>

ไฟล์นี้มีรายละเอียดมาก จึงอยากให้เพื่อนๆเข้าใจในบางส่วนก่อน ได้แก่

  • groupId คือชื่อ package
  • artifactId คือชื่อโปรเจกต์
  • version ใช้แบบมาตราฐาน นี่เรียกว่าเวอร์ชัน alpha ก็จะต่อด้วย -SNAPSHOT

หลังจากติดตั้ง Maven และ JDK 1.8 แล้วต้องกำหนด path มาดูว่า path ที่เครื่องคอมฯของเราพร้อมไหม (ผมถือว่าพวกเราทำเป็นนะครับ)

java -version

ผล

java version “1.8.0_241”
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)

mvn -version

ผล

Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /Users/pros/maven/apache-maven-3.6.3
Java version: 1.8.0_241, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: “mac os x”, version: “10.15.5”, arch: “x86_64”, family: “mac”

จากนั้นแก้ไขชื่อ package ให้ถูกต้อง

package com.example.pros;public class Main {  public static void main(String[] args) {    System.out.println("Hello");  }}

เอาล่ะถ้าเราต้องการทำงานไฟล์ Main.java นี้เราต้องแปลมันเป็น Main.class ก่อน เพื่อทำสิ่งนี้เราจะเรียกคำสั่ง javac <path>/Main.java

ตัวอย่าง

javac src/main/java/com/example/pros/Main.java

ผล

create Main.class

และเมื่อจะทำงาน (รัน) มันก็เรียกคำสั่ง java -classpath <path> <package-path>.Main

ตัวอย่าง

java -classpath src/main/java com.example.pros.Main

ผล

run Main.class

เหล่านี้คือพื้นฐาน แต่เมื่อมาใช้ Maven เราจะไม่เห็นลำดับขั้นตอนอย่างนี้อีกแล้ว เหตุเพราะจะถูกแทนที่ด้วยลำดับขั้นตอนของ Maven ซึ่งจะเล่าต่อไป

Build the Project

จากโปรเจกต์ hello ให้เรียกคำสั่งของ Maven แทนครับ

mvn package

ผล

[ERROR] The goal you specified requires a project to execute but there is no POM in this directory (/Users/pros/works/maven/hello)

เนื่องจากผมสร้าง pom.xml ไว้ผิดสถานที่ที่ Maven เข้าใจได้ จึงต้องย้ายมันไปไว้ที่ hello/pom.xml

หลังจากนั้นรันอีกครั้ง

ผล

Building jar: /Users/pros/works/maven/hello/target/hello-1.0-SNAPSHOT.jar

เราจะได้ .jar มาหนึ่งไฟล์และชื่อของมันเป็นไปตามที่กำหนดไว้ใน pom.xml โดยใช้ artifactId ต่อด้วย version

เอ๋~ไม่ได้ .class มาเหรอ? คำตอบยังคงได้ .class มาครับ แต่ถูกห่อไว้ใน .jar

คำสั่งถัดมาจึงต้องสั่งทำงาน .jar เรียกไปยัง Main.class ที่อยู่ด้านในแทน

java -cp target/hello-1.0-SNAPSHOT.jar <package-path>.Main

ตัวอย่าง

java -cp target/hello-1.0-SNAPSHOT.jar com.example.pros.Main

ผล

run Main.class ใน .jar

ตามตัวอย่างที่เห็น หลังเรียกใช้คำสั่ง mvn package Maven จะทำสิ่งที่เรียกว่า phase ซึ่งแต่ละ phase มีขั้นตอนในการทำงานของตนเอง

แต่ละ phase จะมีขั้นตอนย่อยต่างกัน ตัวอย่างสมมติสั่ง Maven ไปว่า mvn compile สิ่งที่จะเกิดขึ้นคือ

  1. validate
  2. generate-sources
  3. process-sources
  4. generate-resources
  5. process-resources
  6. compile

ถึงตรงนี้จึงกล่าวได้ว่าเมื่อจะใช้งาน Maven ก็ต้องศึกษา phase ต่างๆของมันให้เข้าใจเสียก่อน

เพื่อนๆมือใหม่อาจรู้สึกเหมือนผมในตอนนี้ว่า “มันช่างยุ่งยากนัก” สั่ง javac ทำงานยังดูง่ายกว่าอีก อันนี้ก็จริงครับหากว่าโปรเจกต์เรา dependency ของประดา .jar หรือคลาสที่เราต้องการเรียกใช้งานมีน้อย เมื่อเราเขียนจาวาเป็น framework เช่น Spring Framework หรือ Spring Boot ตอนนั้นเราต้องหาวิธีดูแลพวก .jar ให้ทำงานร่วมกันได้โดยก่อให้เกิด bug น้อยที่สุด เราจะนึกถึง tool พวก build tool และผมกล้าบอกตรงนี้ได้เลยว่า Maven นั้นทรงพลังอย่างมาก

ไว้พบกันใหม่ สวัสดีครับ

--

--