Tuesday, October 04, 2005

Maven-Eclipse-Plugin

ช่วงนี้ทดลองพัฒนา JBI (Java Business Integration) Component อยู่
ก็เลยมีเหตุให้ต้องได้ใช้ Maven-Eclipse-Plugin อีกครั้ง
ก็เลยขอ Review หรือทบทวนตัว plugin นี้อีกครั้ง

ปกติเวลาเราเริ่มต้น project ที่จะใช้ Maven เป็น build tool
เราจะเริ่มด้วยการสร้าง file ที่ชื่อ project.xml กับ project.properties
ตัว project.xml จะเป็น descriptor ที่อธิบาย
  • ชื่อของโปรเจค
  • version ของ project
  • dependencies ของโปรเจค
  • directory ที่ใช้เก็บ source, test


<project>
<pomVersion>2</pomVersion>
<name>Echo</name>
<id>Echo</id>
<currentVersion>1.0</currentVersion>
<package>org.servicemix.demo</package>
<shortDescription>A new JBI component</shortDescription>
<description>A new JBI component</description>
<dependencies>
<dependency>
<id>servicemix</id>
<version>1.0</version>
<type>jar</type>
<url>http://www.servicemix.org</url>
</dependency>
.....
<dependency>
<groupId>servicemix</groupId>
<artifactId>servicemix-client</artifactId>
<version>1.0</version>
<properties>
<jbi.bundle>true</jbi.bundle>
</properties>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<unitTestSourceDirectory>src/test/java</unitTestSourceDirectory>
</build>
</project>


ส่วน project.properties จะทำหน้าที่เป็นตัว customize ข้อมูล
ของ plugin ต่างๆ ให้ประพฤติหรือปฎิบัติตนตามที่เราต้องการ
เช่น ต้องการให้ javac compile โดยมี debug information ด้วย

เมื่อเราเขียน project.xml เสร็จ ก็ให้สั่ง
maven eclipse


Maven-Eclipse-Plugin ก็จะทำการ generate
file .classpath กับ file .project ให้เรา
ซึ่ง 2 file นี้เป็น file หลักที่ eclipse ใช้เก็บข้อมูล project

ที่นี้ลองมาดูว่าเขาเขียน Maven-Eclipse-plugin นี้กันอย่างไร
เริ่มที่ว่า เวลาเราสั่ง maven eclipse นั้น
มันจะเริ่มทำงานที่ไหน อย่างไร

plugin ของ Maven ปกติจะอยู่ใน Directory MAVEN_HOME/plugins
โดยอยู่ในรูป jar file
ซึ่ง maven จะแอบแตก file เหล่านี้เก็บไว้ใน directory $USER_HOME/.maven/cache
โดยแต่ละ plugin จะกลายเป็น 1 sub directory
ในแต่ละ plugin จะมี file หลักๆอยู่ 4 ตัวคือ
  • project.xml
    เป็น file ที่อธิบายถึง plugin นั้น
    โครงสร้างหน้าตาเหมือนกับ project.xml ของ project เรา
  • project.properties
    ตัวนี้ไม่ค่อยได้ใช้อะไรอ
  • plugin.jelly
    file นี้แหล่ะทีเป็นหัวใจของ plugin
    เพราะเป็น file ที่เก็บว่า plugin นี้ทำอะไรได้บ้าง
    รวมทั้งแต่ละ task ที่ทำ มี step หรือขั้นตอนการทำอย่างไร
  • plugin.properties
    file นี้เก็บข้อมูล properties ของ plugin
    ที่สามารถ override จาก project.properties ของเราได้


file plugin.jelly เขียนด้วย Jelly
ซึ่งเป็น template engine แบบหนึ่ง (เหมือนๆพวก jsp, velocity,...)
ถ้าเราลองเปิดดู file นี้จะเห็นว่ามีการ declare goal ที่ืชื่อ eclipse ไว้
<!--==================================================================-->
<!-- Generate Eclipse .project and .classpath files -->
<!--==================================================================-->
<goal name="eclipse"
description="Generate Eclipse project files"
prereqs="eclipse:generate-project, eclipse:generate-classpath">
<ant:echo>Now refresh your project in Eclipse (right click on the project and
select "Refresh")</ant:echo>
</goal>

ลักษณะของ goal จะเขียนเหมือนกับ ant target
ก็คือ ระบุว่ามี depend ถึง goal ไหนหรือไม่
task ภายในที่ต้องทำมีอะไรบ้าง
โดยส่วนใหญ่แล้ว maven plugin จะส่งต่อไปให้ ant task
เป็นตัวทำงานจริง
(จริงๆมันเป็นลูกผสม ระหว่าง ant กับ jelly
ปัญหาของ ant คือ มันไม่ได้เป็น language ทำให้เขียน build file
ไม่ได้เต็มที่. maven ก็เลยใส่ syntax ของ jelly เข้าไปผสม)

ถ้าลองตามไปดู goal eclipse:generate-project
ที่ถูกอ้างถึง จะเห็น source code ดังนี้
<goal name="eclipse:generate-project"
description="Generate Eclipse .project file">

<ant:echo>Creating ${basedir}/.project ...</ant:echo>
<j:file name="${basedir}/.project" prettyPrint="true" xmlns="dummy">
<j:import file="${plugin.resources}/templates/project.jelly" inherit="true"/
>
</j:file>

</goal>


อธิบายได้ง่ายๆคือ มันจะสร้าง file ที่ชื่อ .project
โดยเนื้อหาของ file ได้มาจากการ run template ที่ชื่อ template/project.jelly

ถ้าลองตามไปดู file template/project.jelly
ก็จะเห็น file หน้าตาประมาณนี้
<projectDescription>
<name>${pom.artifactId}</name>
<comment>${pom.description}</comment>
<projects>
<j:forEach var="lib" items="${pom.artifacts}">
<j:set var="eclipseDependency"
value="${lib.dependency.getProperty('eclipse.dependency')}"/>
<j:if test="${eclipseDependency == 'true'}">
<project>${lib.dependency.artifactId}</project>
</j:if>
</j:forEach>
</projects>

....

</projectDescription>


ผลลัพท์ของการ run template ข้างบน
จะได้ file หน้าตาอย่างนี้ออกมา
<projectDescription>
<name>Echo</name>
<comment>A new JBI component</comment>
<projects>
</projects>
...
</projectDescription>


จะเห็นได้ว่าวิธีการใช้ template จะไม่ค่อยยากนัก
เสียแต่ว่าดูแล้วลายตาไปหน่อย

Related link from Roti

No comments: