點進來讀這篇文章的朋友,我假定你已經知道maven的基本知識,也知道Eclipse,知道Eclipse是基於OSGi,初步瞭解Eclipse插件開發或者說OSGi模塊化開發。如果對這些知識不瞭解,甚至完全沒有聽過,那請繞開本文。
Maven簡單來說是Java世界的一種新型的build工具,比ant的最大好處是依賴的管理,以及配置文件的可讀性,可複用性,可擴展性。Maven的配置文件稱爲POM,即Project Object Model。在Maven中,每一個插件或者模塊都由groupId,artifactId,version唯一標示。還有兩個可選的標示元素,一個是packaging,默認支持的選項有pom,jar,maven-plugin,ejb,war,ear,rar,par等,maven會根據packaging設置的不同爲模塊執行不同的目標(goal);另一個是classifier,一般用不上。
最簡單的pom
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
關於Maven的廢話不多說,直接開始Tycho。如果說Maven的出現是一羣Java程序員受不了繁瑣的插件依賴管理,受不了冗長的ant build.xml文件而創造出來的,那Tycho則是一羣Eclipse、OSGi插件開發人員受不了重複地配置類似的Maven pom.xml而創造出來的。Tycho大大簡化了Eclipse、OSGi插件中的pom.xml,它實際上是一系列專用於build Eclipse插件和OSGi模塊的maven插件的集合。
熟悉Eclipse插件和OSGi模塊開發的程序員都知道,他們有自己的一套metadata用來描述自己的依賴,自己的各項配置。
比如MANIFEST.MF文件,就包含了模塊名稱,版本,依賴等豐富的信息
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Dialog Editor
Bundle-SymbolicName: com.company.app; singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: Company
Require-Bundle: org.eclipse.ui,
org.eclipse.graphiti,
org.eclipse.graphiti.ui,
org.eclipse.core.runtime;bundle-version="3.8.0",
javax.inject;bundle-version="1.0.0",
org.eclipse.e4.core.di;bundle-version="1.1.0",
org.eclipse.e4.ui.workbench;bundle-version="0.10.2",
org.eclipse.e4.ui.di;bundle-version="0.10.1",
org.eclipse.e4.ui.services;bundle-version="0.10.1",
org.eclipse.core.resources;bundle-version="3.8.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
還有build.properties,定義了所有需要在runtime用到的非代碼文件(比如圖片,配置文件等)
source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
META-INF/,\
.,\
icons/,\
MyModel.e4xmi
以及product文件
<?xml version="1.0" encoding="UTF-8"?>
<?pde version="3.5"?>
<product name="e4 SDK" uid="org.eclipse.e4.workbench.sdk" id="org.eclipse.e4.ui.examples.legacy.workbench.product" application="org.eclipse.ui.ide.workbench" version="0.9.0.@qualifier@" useFeatures="true" includeLaunchers="true">
<aboutInfo>
<image path="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse_lg.gif"/>
</aboutInfo>
<configIni use="default">
</configIni>
<launcherArgs>
<programArgs>--launcher.XXMaxPermSize 256m</programArgs>
<vmArgs>-Xms256m -Xmx512m</vmArgs>
<vmArgsMac>-Xdock:icon=../Resources/Eclipse.icns -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
</launcherArgs>
<windowImages i16="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.gif" i32="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.gif" i48="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.gif"/>
<splash
location="org.eclipse.e4.ui.examples.legacy.workbench" />
<launcher name="eclipse">
<solaris/>
<win useIco="false">
<bmp/>
</win>
</launcher>
<vm>
</vm>
<plugins>
</plugins>
<features>
<feature id="org.eclipse.sdk"/>
<feature id="org.eclipse.equinox.p2.user.ui"/>
<feature id="org.eclipse.equinox.p2.user.ui.source"/>
<feature id="org.eclipse.emf.sdk"/>
<feature id="org.eclipse.wst.xml_ui.feature"/>
<feature id="org.eclipse.gef"/>
<feature id="org.eclipse.rcp.configuration"/>
<feature id="org.eclipse.e4.sdk.runtime.feature"/>
<feature id="org.eclipse.e4.sdk.source.feature"/>
<feature id="org.eclipse.releng.tools"/>
</features>
<configurations>
<plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="4" />
<plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
<plugin id="org.eclipse.equinox.ds" autoStart="true" startLevel="2" />
<plugin id="org.eclipse.equinox.p2.reconciler.dropins" autoStart="true" startLevel="4" />
<plugin id="org.eclipse.equinox.simpleconfigurator" autoStart="true" startLevel="1" />
<plugin id="org.eclipse.update.configurator" autoStart="true" startLevel="3" />
<property name="eclipse.buildId" value="@qualifier@" />
</configurations>
</product>
爲了優化對Eclipse插件和OSGi模塊的build,Tycho提供了專門的packaging,用來處理專門的模塊生命週期,最典型的比如eclipse-repository,配合tycho-p2-director-plugin,直接就可以讀懂product文件,build整個Eclipse RCP的product。
啓用Tycho很簡單,把下面的properties和build標籤加入到parent pom文件即可,其中0.15.0是截止2012.8.26 Tycho最新的版本。
<properties>
<tycho-version>0.15.0</tycho-version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
下面的repository標籤用來設定一個Eclipse Indigo (視需要改變)的官方p2倉庫,從這個倉庫可以獲取Tycho以及Eclipse插件或者OSGi模塊化開發所需的大量編譯好的模塊
<repository>
<id>eclipse-indigo</id>
<layout>p2</layout>
<url>http://download.eclipse.org/releases/indigo</url>
</repository>
因爲子pom可以從父pom繼承到插件的配置信息,所以一般推薦在parent pom中定義插件配置,另外子pom也有重寫(override)配置的權利。
比如我們來定義target-platform-configuration插件(用來build最後的product)的配置,告訴Tycho的這個maven插件我想要分別對windows,linux,macos三種操作系統build 專門的product,這樣Tycho在build product的時候就會根據不同的os,選用不同的環境包併入最後的product中。
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<environments>
<environment>
<os>win32</os>
<ws>win32</ws>
<arch>x86</arch>
</environment>
<environment>
<os>linux</os>
<ws>gtk</ws>
<arch>x86_64</arch>
</environment>
<environment>
<os>macosx</os>
<ws>cocoa</ws>
<arch>x86_64</arch>
</environment>
</environments>
</configuration>
</plugin>
接下來介紹build Eclipse插件、OSGi模塊的各種專門的packaging
1、普通的Eclipse插件、OSGi模塊
<groupId>Some-Group-Id</groupId>
<artifactId>Bundle-SymbolicName</artifactId>
<version>Bundle-Version</version>
<packaging>eclipse-plugin</packaging>
2、feature模塊(定義feature,feature是插件的集合,我們在給Eclipse安裝插件的時候往往安裝的是feature,而不是安裝一個個的plugin jar)
<groupId>Some-Group-Id</groupId>
<artifactId>FeatureId</artifactId>
<version>FeatureVersion</version>
<packaging>eclipse-feature</packaging>
3、p2倉庫(爲了發佈,以及未來更新的各種方便,一般建議創建專門的一個模塊定義倉庫)
<groupId>Some-Group-Id</groupId>
<artifactId>RepositoryName</artifactId>
<version>Version</version>
<packaging>eclipse-repository</packaging>
4、product產品
<groupId>Some-Group-Id</groupId>
<artifactId>RepositoryName</artifactId>
<version>Version</version>
<packaging>eclipse-repository</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>materialize-products</id>
<goals>
<goal>materialize-products</goal>
</goals>
</execution>
<execution>
<id>archive-products</id>
<goals>
<goal>archive-products</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
5、測試模塊
把測試模塊單獨build是Tycho的一個特色,也是OSGi模塊化開發的特色。很多人習慣把源代碼放到main/src底下,把測試代碼放到同一個項目的test文件夾底下,而在OSGi中,測試代碼應該寫在單獨的模塊裏。這樣最大的好處是執行的時候測試模塊只有在測試階段才執行,在打包階段不執行,就不會被打進最後的產品包裏。
只要把packaging設置成下面的 eclipse-test-plugin,Tycho就知道這是一個測試模塊,只有在測試階段才build它。
<groupId>Some-Group-Id</groupId>
<artifactId>Bundle-SymbolicName</artifactId>
<version>Bundle-Version</version>
<packaging>eclipse-test-plugin</packaging>
最後放幾個官方的鏈接:
http://maven.apache.org/guides/introduction/introduction-to-the-pom.html
http://www.eclipse.org/tycho/
http://wiki.eclipse.org/Tycho/Reference_Card