Thứ Ba, 21 tháng 11, 2017

Maven 3 : Giới thiệu

 1. Giới thiệu

Apache Maven là công cụ quản lý dự án (project management tool) chủ yếu là các dự án Java dựa trên khái niệm mô hình đối tượng dự án (project object model : POM). Nó cho phép thực hiện các chức năng của một công cụ xây dựng dự án (build tool) như tiền xử lý, biên dịch, chạy kiểm thử, cài đặt, đóng gói, triển khai... (preprocess, compile, test, install, deploy, ...). Ngoài ra nó còn cho phép phát sinh báo cáo kiểm thử (report) và tài liệu (document), quản lý các phụ thuộc (dependency), các plugin, các dự án con...

Lược qua vài nét về Maven, đầu tiên nó nằm trong dự án Jakarta Alexandria, được tách ra thành một dự án riêng mang tên Maven vào năm 2002, đây là Maven 1. Maven 2 ra đời năm 2005 được cải tiến về nhiều mặt như về hiệu năng, tính ổn định và có thêm những tính năng mới, tuy nhiên nó hoàn toàn không tương thích với Maven 1. Năm 2010, Maven 3 chính thức xuất xưởng với phiên bản 3.0, lần này thì nó tương thích với Maven 2.

Muốn hiểu và sử dụng Maven ta cần biết về  : tập tin cấu hình pom.xml; việc sử dụng một số quy ước về cấu trúc dự án và các tên thư mục quy ước của Maven, các tên thư mục này có thể cá nhân hóa (customize) được; vòng đời xây dựng (build lifecycle)

2. Quy ước thay cho cấu hình (Convention Over Configuration)

Maven áp dụng nguyên tắc Quy ước thay cho cấu hình để đơn giản hóa việc cấu hình và đồng nhất cấu trúc của các dự án dùng maven xây dựng. Maven định nghĩa bố cục các thư mục trong dự án mà người dùng phải tuân thủ, tuy nhiên ta cũng có thể cá nhân hóa và thay đổi tên gọi hay vị trí thư mục này theo ý mình. Ngoài định nghĩa các thư mục dự án, nguyên tắc này còn được maven áp dụng trong nhiều tiến trình khác như việc biên dịch, đóng gói dự án, phát sinh web sites, ...

Cụ thể Maven định nghĩa bố cục các thư mục chuẩn trong một thư mục dự án phát triển bằng java trong super POM như sau :
pom.xml                Tập tin cấu hình 
src/main/java          Thư mục chứa mã java
src/main/resources     Thư mục chứa các tập tin tài nguyên khác (.properties, .xml ...)
src/main/filters       Thư mục chứa các tập tin filter ( .properties cho resources)
src/main/assembly      Thư mục chứa miêu tả assembly
src/main/config        Thư mục chứa các tập tin cấu hình
src/main/scripts       Thư mục chứa các tập tin script (.js chẳng hạn)
src/main/webapp        Thư mục chứa mã của ứng dụng web (thư mục WEB-INF, .html, .jsp, ...)
src/test/java          Thư mục chứa mã nguồn phần kiểm thử
src/test/resources     Thư mục chứa các tập tin tài nguyên khác của kiểm thử (.properties...)
src/test/filters       Thư mục chứa các tập tin filter của phần kiểm thử (.properties)
src/site               Site
target                 Thư mục maven phát sinh để chứa các tập tin xuất
target/classes         Thư mục maven phát sinh khi biên dịch dự án
LICENSE.txt            Thông tin bản quyền
NOTICE.txt             Ghi chú về các thông tin cần thiết khác của đề án
README.txt             Thông tin về đề án

3. Vòng đời xây dựng (build lifecycle)

Một vòng đời maven bao gồm một chuỗi có thứ tự các giai đoạn (phase), mỗi giai đoạn định nghĩa một đích (goal). Trong maven có ba vòng đời dựng sẵn (built-in) là clean, default (còn gọi là build) và site. Các vòng đời của Maven được định nghĩa trong tập tin components.xml : Maven 2.xMaven 3.x

Một số giai đoạn được maven mặc định gắn với một đích. Đối với các vòng đời dựng sẵn nói trên, sự gắn kết này phụ thuộc vào việc đóng gói (packaging) artifact (tức project hay dự án). Và nó được định nghĩa trong tập tin components.xml đối với Maven 2.x, còn Maven 3.x thì chúng được định nghĩa trong tập tin  default-bindings.xml. Ta gọi các gắn kết này là các gắn kết vòng đời dựng sẵn (built-in lifecycle bindings).

a. Vòng đời clean
Vòng đời clean xử lý việc làm sạch dự án, tức xóa những thư mục do maven phát sinh trong việc xây dựng dự án, gồm ba giai đoạn theo thứ tự : pre-clean, clean, post-clean

Trong vòng đời clean, giai đoạn clean được định nghĩa trỏ tới đích mặc định là clean:clean , đích này có tác dụng xóa toàn bộ các thư mục phát sinh khi build đề án, cụ thể là thư mục  ${basedir}/target được định nghĩa trong super POM.

Vòng đời clean có định nghĩa một gắn kết vòng đời sau:
clean       -->    clean:clean

Tức khi gõ lệnh mvn clean sẽ tương đương với việc gõ lệnh gọi trực tiếp giai đoạn clean để thực thi đích clean (clean:clean) như sau mvn clean:clean. Lệnh này thực hiện giai đoạn clean và tất cả các giai đoạn trước nó tức là cả pre-clean.

b. Vòng đời default
Vòng đời default nắm việc xây dựng (build) và triển khai (deploy) một dự án, bao gồm một chuỗi các giai đoạn theo thứ tự sau :
validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy

Khi ta thực thi một trong các giai đoạn này, maven không chỉ thực thi giai đoạn đó mà còn thực thi tất cả các giai đoạn đứng trước nó. Chẳng hạn, khi ta thực hiện mvn deploy thì maven sẽ thực thi tất cả các giai đoạn liệt kê ở trên vì deploy là giai đoạn cuối cùng của vòng đời này.

Các gắn kết vòng đời default :
Các gắn kết vòng đời dựng sẵn cho đóng gói ejb / ejb3 / jar / par / rar / war
process-resources        resources:resources
compile                  compiler:compile
process-test-resources   resources:testResources
test-compile             compiler:testCompile
test                     surefire:test
package                  ejb:ejb hay ejb3:ejb3 hay jar:jar hay par:par hay rar:rar hay war:war
install                  install:install
deploy                   deploy:deploy

Các gắn kết vòng đời dựng sẵn cho đóng gói ear
generate-resources     ear:generate-application-xml
process-resources      resources:resources
package                ear:ear
install                install:install
deploy                 deploy:deploy

Các gắn kết vòng đời dựng sẵn cho đóng gói maven-plugin
generate-resources         plugin:descriptor
process-resources          resources:resources
compile                    compiler:compile
process-test-resources     resources:testResources
test-compile               compiler:testCompile
test                       surefire:test
package                    jar:jar và plugin:addPluginArtifactMetadata
install                    install:install
deploy                     deploy:deploy

Các gắn kết vòng đời dựng sẵn cho đóng gói pom
package     site:attach-descriptor
install     install:install
deploy      deploy:deploy

c. Vòng đời site
Vòng đời site nhằm tạo trang tài liệu cho dự án

d. Một số lệnh maven

Trong trường hợp các lệnh sau được gọi tại  thư mục dự án cha, thì các lệnh này sẽ thực thi trên toàn thể các dự án con của dự án này.

Thích ứng hoá thư mục dự án cho eclipse bằng cách phát sinh các tập tin .project .classpath với lệnh sau :
$ mvn eclipse:eclipse

Biên dịch thư mục dự án
$ mvn install

Xoá các tập tin biên dịch trong thư mục target:
$ mvn clean

Có thể kết hợp các lệnh này cùng lúc theo thứ tự (xoá, biên dịch, bỏ qua không thực thi các kiểm thử (test))
$ mvn clean install -DskipTests

Có thể kết hợp các lệnh này cùng lúc theo thứ tự (xoá, biên dịch, thực thi các kiểm thử (test) có tên tận cùng bằng)
$ mvn clean test -Dtest=*<name>

Đóng gói (jar, ear, war) tuỳ theo cấu hình trong tập tin pom.xml
$ mvn package

Đóng gói và không thực thi các kiểm thử (test)
$ mvn clean package -DskipTests

Phân tích sự phụ thuộc giữa các thư viện (jar), có thể dùng để tìm các jar trùng lập:
$ mvn dependency:analyze-report

Giúp giải quyết vấn đề thiếu các thư viện phụ thuộc (bằng cách tải chúng về):
$ mvn dependency:resolve

Hiển thị cây các thư viện phụ thuộc:
$ mvn dependency:tree

4. Tập tin pom.xml

Tập tin pom.xml định nghĩa một dự án (project) : định danh của nó là gì, bao gồm những gì, được đóng gói như thế nào (jar, war, ear ...), có dự án cha hay không, có những phụ thuộc nào ...
Tập tin pom.xml của thư mục gốc parent
<?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>vn.openspace</groupId>
    <artifactId>parent</artifactId>
    <version>0.1.0</version>
    <packaging>pom</packaging>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-archetype-plugin</artifactId>
                    <version>2.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
        
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-archetype-plugin</artifactId>
                <version>2.1</version>
            </plugin>
        </plugins>
    </build>
</project>

5. Cài đặt Maven

a. Cài Maven trong Ubuntu
Trước khi cài đặt bằng apt-get, ta cần cập nhật nguồn trước với lệnh sau
$ sudo apt-get update

Sau đó ta có thể kiểm xem gói cần cài đặt (maven2 để tải về maven2; maven3 để tải về maven3) có trong nguồn hay không với lệnh sau:
$ apt-cache search maven3

Cài đặt maven3
$ sudo apt-get install maven3

Gõ lệnh sau để tạo thư mục .m2 tại thư mục gốc
$ mvn

b. Cài Maven 3 trong Windows
Maven cần có Java đã được cài đặt và biến môi trường JAVA_HOME (=C:\Program Files\Java\jdk1.7.0_51 chẳng hạn) đã được định nghĩa để có thể hoạt động.

Tải maven về tại đây http://maven.apache.org/download.cgi

Ở đây tôi tải phiên bản apache-maven-3.1.1-bin.zip , sau đó giải nén gói này tại thư mục D:\maven chẳng hạn.

Rồi thêm vào cuối biến môi trường Path đường dẫn đến ";D:\maven\apache-maven-3.1.1\bin". Sau đó để kiểm tra maven đã hoạt động hay chưa ta mở một màn hình lệnh command line (cmd) và gõ lệnh sau :
$ mvn -version
Lệnh này cho biết phiên bản của maven, đường dẫn đến Maven home và Java home mà ta đã định nghĩa trong biến môi trường.

6. Dùng archetype để tạo các dự án

Một số archetype :

org.apache.maven.archetypes:maven-archetype-archetype (An archetype which contains a sample archetype.)
org.apache.maven.archetypes:maven-archetype-j2ee-simple (An archetype which contains a simplifed sample J2EE application.)
org.apache.maven.archetypes:maven-archetype-marmalade-mojo (-)
org.apache.maven.archetypes:maven-archetype-mojo (An archetype which contains a sample a sample Maven plugin.)
org.apache.maven.archetypes:maven-archetype-plugin (An archetype which contains a sample Maven plugin.)
org.apache.maven.archetypes:maven-archetype-plugin-site (An archetype which contains a sample Maven plugin site. This archetype can be layered upon an    existing Maven plugin project.)
org.apache.maven.archetypes:maven-archetype-portlet (An archetype which contains a sample JSR-268 Portlet.)
org.apache.maven.archetypes:maven-archetype-profiles (-)
org.apache.maven.archetypes:maven-archetype-quickstart (An archetype which contains a sample Maven project.)
org.apache.maven.archetypes:maven-archetype-site (An archetype which contains a sample Maven site which demonstrates some of the supported document types like APT, XDoc, and FML and demonstrates how to i18n your site. This archetype can be layered upon an existing Maven project.)
org.apache.maven.archetypes:maven-archetype-site-simple (An archetype which contains a sample Maven site.)
org.apache.maven.archetypes:maven-archetype-webapp (An archetype which contains a sample Maven Webapp project.)


org.codehaus.mojo:gwt-maven-plugin (Maven plugin for the Google Web Toolkit.)
org.codehaus.mojo:javascript-ria-archetype (A JavaScript Rich Internet Application template using jQuery and jQuery UI.)
org.codehaus.mojo.archetypes:appclient-javaee6 (-)
org.codehaus.mojo.archetypes:appclient-javaee7 (Archetype for an Application Client package using Java EE 7.)
org.codehaus.mojo.archetypes:appclient-jee5 (-)
org.codehaus.mojo.archetypes:appframework (Archetype for creating application based on JSR 296)
org.codehaus.mojo.archetypes:ear-j2ee14 (-)
org.codehaus.mojo.archetypes:ear-javaee6 (-)
org.codehaus.mojo.archetypes:ear-javaee7 (Archetype for EAR package using Java EE 7)
org.codehaus.mojo.archetypes:ear-jee5 (-)
org.codehaus.mojo.archetypes:ejb-j2ee13 (-)
org.codehaus.mojo.archetypes:ejb-j2ee14 (-)
org.codehaus.mojo.archetypes:ejb-javaee6 (-)
org.codehaus.mojo.archetypes:ejb-javaee7 (Archetype for an EJB package using Java EE 7.)
org.codehaus.mojo.archetypes:ejb-jee5 (-)
org.codehaus.mojo.archetypes:javafx (Archetype for creating a JavaFX application)
org.codehaus.mojo.archetypes:nbm-archetype (Archetype for development of NetBeans modules in Maven.)
org.codehaus.mojo.archetypes:nbm-osgi-archetype (Archetype for development of NetBeans modules that can depend on OSGi bundles.)
org.codehaus.mojo.archetypes:nbm-suite-root (Root project archetype for creating multi module projects developing NetBeans IDE modules. Approximately similar in functionality to module suites in NetBeans Ant projects.)
org.codehaus.mojo.archetypes:netbeans-platform-app-archetype (Archetype for sample application based on NetBeans Platform. Creates parent POM with branding and empty NBM project.)
org.codehaus.mojo.archetypes:osgi-archetype (Archetype for development of OSGi bundles using Apache Felix Maven plugin)
org.codehaus.mojo.archetypes:pom-root (Root project archetype for creating multi module projects)
org.codehaus.mojo.archetypes:sample-javafx (Sample archetype for creating a JavaFX application)
org.codehaus.mojo.archetypes:webapp-j2ee13 (-)
org.codehaus.mojo.archetypes:webapp-j2ee14 (-)
org.codehaus.mojo.archetypes:webapp-javaee6 (-)
org.codehaus.mojo.archetypes:webapp-javaee7 (Archetype for a web application using Java EE 7.)
org.codehaus.mojo.archetypes:webapp-jee5 (-)


Chú ý lần đầu tiên dùng maven, trong trường hợp này là ta gọi lệnh mvn  archetype:generate, ta sẽ thấy hơi lâu vì Maven sẽ tải về các thư viện jar và các plugin nó sử dụng. Những lần sau sẽ nhanh hơn nhiều vì những thư viện này đã được lưu lại trong local repository tức thư mục .m2

7. Cấu hình Maven

Mặc định maven sẽ tải các thư viện từ central repository. Nếu muốn cấu hình repository, ta tạo tập tin settings.xml (trong đó định nghĩa repository) tại vị trí ~/.m2/settings.xml (~ là vị trí thư mục gốc của người dùng, trong Windows là C:\Users\<thư mục người dùng> chẳng hạn)

Một ví dụ về tập tin settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <mirrors>
    <mirror>
      <id>internal</id>
      <mirrorOf>*</mirrorOf>
      <url>http://path-to-repository</url>
    </mirror>
  </mirrors> 
  <servers>
      <server>
          <id>remote-repository</id>
          <username>toan</username>
          <password>toan</password>
      </server>
  </servers>
</settings> 

9. Thuộc tính của maven (Maven properties)
Thuộc tính trong maven bao giờ cũng được bao giữa ${}. Ta có thể dùng các thuộc tính định nghĩa trước của Maven hoặc tự định nghĩa các thuộc tính trong tập tin pom.xml hoặc các tài nguyên khác mà maven sử dụng, chẳng hạn maven settings, maven profiles ....

a. Thuộc tính project (maven project properties)
 Ta có thể dùng tiền tố project.* để tham chiếu đến các giá trị định nghĩa trong tập tin pom (kể cả parent pom).

Đồng thời tiền tố này có thể dùng để tham chiếu đến các thuộc tính của org.apache.maven.model.Model, chẳng hạn khi ta dùng ${project.build.directory} là tương đương với việc gọi hàm model.getBuild().getDirectory()

Sau đây là danh sách một số thuộc tính thường dùng theo cách vừa kể :
${project.groupId}
${project.version}
${project.artifactId}
${project.name}
${project.description}
${project.build.sourceDirectory} 
${project.build.scriptSourceDirectory}    
${project.build.testSourceDirectory}     
${project.build.outputDirectory}     
${project.build.testOutputDirectory} 
${project.build.directory}
${project.build.finalName}
${project.baseUri}
${project.parent} : giá trị trỏ đến đề án cha

b. Thuộc tính settings (maven settings properties)
Dùng tiền tố settings.* để tham chiếu đến các giá trị định nghĩa trong  ~\.m2\settings.xml. Chẳng hạn:
${settings.localRepository}

c. Thuộc tính biến môi trường (environnement variables properties)
Dùng tiền tố env.* để tham chiếu đến các giá trị của biến môi trường.Chẳng hạn
${env.PATH} : giá trị biến môi trường Path
${env.HOME} : trỏ đến thư mục gốc của người dùng
${env.JAVA_HOME} : trỏ đến thư mục cài đặt java định nghĩa trong biến môi trường
${env.M2_HOME} : trỏ đến thư mục cài đặt maven định nghĩa trong biến môi trường

d. Thuộc tính hệ thống của Java (Java system properties)
Maven cho phép truy xuất các thuộc tính của java.lang.System. Các thuộc tính có thể dùng dưới dạng gọi phương thức System.getProperty(), thì ta có thể tham chiếu đến nó bằng thuộc tính maven. Danh sách các thuộc tính hệ thống Java :

${java.version} : Java Runtime Environment version
${java.vendor} : Java Runtime Environment vendor
${java.vendor.url} : Java vendor URL
${java.home} : Java installation directory
${java.vm.specification.version} : Java Virtual Machine specification version
${java.vm.specification.vendor} : Java Virtual Machine specification vendor
${java.vm.specification.name} : Java Virtual Machine specification name
${java.vm.version} : Java Virtual Machine implementation version
${java.vm.vendor} : Java Virtual Machine implementation vendor
${java.vm.name} : Java Virtual Machine implementation name
${java.specification.version} : Java Runtime Environment specification version
${java.specification.vendor} : Java Runtime Environment specification vendor
${java.specification.name} : Java Runtime Environment specification name
${java.class.version} : Java class format version number
${java.class.path} : Java class path
${java.ext.dirs} : Path of extension directory or directories
${os.name} : Operating system name
${os.arch} : Operating system architecture
${os.version} : Operating system version
${file.separator} : File separator ("/" on UNIX, "\" on Windows)
${path.separator} : Path separator (":" on UNIX, ";" on Windows)
${line.separator} : Line separator ("\n" on UNIX and Windows)
${user.name} : User’s account name
${user.home} : User’s home directory
${user.dir} : User’s current working

e. Một số thuộc tính tiền định nghĩa khác
${basedir} : trỏ đến thư mục đang chứa tập tin pom.xml
${version} : tương đương với ${project.version}

f. Thuộc tính người dùng định nghĩa

Người dùng có thể định nghĩa các thuộc tính trong thẻ properties trong tập tin pom.xml, chẳng hạn như sau :
<project>
...
  <properties>
     <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
  </properties>
...
</project>

Khi đó ${endorsed.dir} có giá trị là "./target/endorsed"; thư mục  này nằm trong thư mục gốc của dự án.



Không có nhận xét nào:

Đăng nhận xét