Suppose we have a set of Eclipse project in a workspace. Some of them are core library bundles (ends with *.core), some of them are GUI plugins (ends with *gui.plugin) and one is a main RCP application (*.rcpapp). Projects depends on each other using Eclipse IDE built-in plugin dependencies. We would like to automate whole build process - make a headless build. Lets go through the process of creation all nesecarry steps.
Eclipse terminology
Before I begin I would like to clear one thing - I will sometimes refer to some projects as "bundles". This term comes from OSGi and means a "module". Eclipse Platform used a term "plugin" for "module" before it adapted OSGi. For this reason by refering "bundle" I will also mean "plugin" and vice versa. Let me explain some basic terms:
- Plugin (or plug-in) is a basic packaging unit. It consists of manifest file (standard Java MANIFEST.MF) and plugin.xml. Basically it is an OSGi bundle (the manifest) with additional info (plugin.xml). It is deployed in a directory or in a JAR file.
- Feature is basically a set of plugins that can be installed into RCP application as a whole. Feature defines which plugins are required and on which plugins these plugins depends on. Feature is basic unit for updating facilities under Eclipse. It usually comes with additive descriptive information like licensing, readmes, welcome pages, about boxes etc.
- Fragment is a kind of "wrapper" around plugin that adds some additional resources such as additional national language translations. Fragments are used for shippingg function that may be added later, since they do not require repackaging or reinstalling the original plugins.
- Rich Client Platform Application (or RCP Application) is a final application (the one with executable file) that runs one or more plugins(fragments) and/or features. The RCP application can be plugin based or feature based which means its expecting plugins or features to be installed. Features are the preferred way. Please note the Rich Client Platform (without the word "Application") stands for platform as a whole.
Example description
First of all let me introduce my example I will show the whole process on. Its code-named project "Puma". It is an RCP application with one feature installed (code-name "wm") and this feature has only one plugin (the project is in initial phase). So basically it is a set of Eclipse projects:
- com.pike.commons.graph - a core library (bundle/plugin without GUI)
- com.pike.commons.logging - a core library (bundle/plugin without GUI)
- com.pike.puma.diego.core - a core library (bundle/plugin without GUI)
- com.pike.puma.wm.is.dump.core - a core library (bundle/plugin without GUI)
- com.pike.puma.wm.is.dump.util - a core library (bundle/plugin without GUI)
- com.pike.puma.wm.is2isd.cmd - standalone command line application
- com.pike.puma.wm.isd2dita.cmd - standalone command line application
- com.pike.puma.rcpapp - Eclipse RCP application
- com.pike.puma.wm.is.dump.gui.plugin - plugin with GUI functionality
- com.pike.puma.wm.feature - the feature (set of plugins - with only one member in this example) for the main production function
These are input artifact, what would we like to generate is one RCP application deployment (plugins/ and features/ folder with puma.exe). It must be executed from command line.
Build project
Let us create a build project - folder containing the main build script. I call it "com.pike.puma.build" and I will create it as generic (empty) Eclipse project. After that I copy the file build.properties from my eclipse insallation dir/org.eclipse.pde.build/templates/headless-build. Do not copy other files!
After refreshing (F5) look into build.properties file and edit these basic properties:
- topLevelElementType - should be set to "feature" since we need to build our feature (called "wm").
- topLevelElementId is set to "com.pike.puma.wm.feature" and represents the id of the feature to build.
- buildDirectory is set to "${user.home}/eclipse.build" but we can modify to our needs. This is the directory where building take place and it should NOT be in your revision version control system.
- configs value is set to include all architectures to build. For a product build set this to desired platforms. See the template file comments for example syntax. You also have to install delta pack into your SDK - we will discuss this later.
- archivePrefix we set to "puma". Its defining how the directory will be named. No big deal.
- base is set to the SDK which we are compiling against. The best is to have RCP SDK separated from the Eclipse RCP IDE installation and I highly recommend to install RCK SDK Delta Pack which enables you to compile for multiple platform. In my case I have set it to c:/eclipse/eclipse-rcp-sdk-3.4.0. For example if you want to build your application against RCP SDK 3.4 download and unpack these directories (keeping "eclipse" directory) and also set it as your Target Platform in your Eclipse IDE preferences:
- http://download.eclipse.org/eclipse/downloads/drops/R-3.4-200806172000/download.php?dropFile=eclipse-RCP-SDK-3.4-win32.zip
- http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.4-200806172000/eclipse-3.4-delta-pack.zip
- javacSource and javacTarget should be set to "1.5" if you are using Java 5.0.
Now add these three additional properties that are not in the template. It will be used in the "main" build script which we are going to create later on.
- eclipseLocation is the base directory of your Eclipse RCP IDE installation, for example c:/eclipse/eclipse-rcp-3.4.0. We need to define this because we will be launching Eclipse built-in Ant.
- equinoxLauncherPluginVersion is the version of the org.equinox.launcher JAR library that you find in your Eclipse RCP IDE "plugins" directory. For Eclipse RCP IDE version 3.4.0 this should be set to 1.0.100.v20080509-1800.
- pdeBuildPluginVersion is the version of the org.eclipse.pde.build. Its set to 3.4.0.v20080604 for the 3.4.0 version.
Example of the build.properties follows (its better to modify the template than use this example):
# properties for main build script
eclipseLocation=c:/eclipse/eclipse-rcp-3.4.0
equinoxLauncherPluginVersion=1.0.100.v20080509-1800
pdeBuildPluginVersion=3.4.0.v20080604
# properties for eclipse build scripts (sorted without comments!)
archivePrefix=pumabase=c:/eclipse/eclipse-rcp-sdk-3.4.0-dp
basearch=x86
baseLocation=${base}/eclipse
baseos=win32
basews=win32
buildDirectory=c:/EXPORT/PUMA_ANT/com.pike.puma.wm.feature
buildId=TestBuild
buildLabel=${buildType}.${buildId}
buildType=I
collectingFolder=${archivePrefix}
configs = *, *, *
eclipseBaseURL=${eclipseURL}/eclipse-platform-${eclipseBuildId}-win32.zip
eclipseBuildId=<Id of Eclipse build to get>
eclipseURL=<url for eclipse download site>
filteredDependencyCheck=false
javacDebugInfo=false
javacFailOnError=true
javacSource=1.5
javacTarget=1.5
javacVerbose=true
logExtension=.log
mapsCheckoutTag=HEAD
mapsRepo=:pserver:anonymous@example.com/path/to/repo
mapsRoot=path/to/maps
mapsTagTag=v${buildId}
product=/com.pike.puma.rcpapp/etc/configurations/puma_all.product
resolution.devMode=false
runPackager=true
skipBase=true
skipFetch=true
skipMaps=true
tarargs=
timestamp=007
topLevelElementId = com.pike.puma.wm.feature
topLevelElementType = feature
zipargs=
Now create new file called build.xml (the main build file). This build file was created by Patrick Paulin from www.rcpquickstart.com and I have slightly modified it. So you do - the script must prepare the build directory structure (plugins and features directories) and copy the source codes into it. Then it executes the internal Eclipse Ant to start the build process. Beware of wrapped lines!
<!--
This program and the accompanying materials are made available
under the terms of the Eclipse Public License v1.0 which
accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
This build script creates a build directory containing the plugins
and features to be built, and then kicks off the PDE build process.
You could just as easily do this from a shell script or cron job.
Also, the script can be run inside the Eclipse IDE by choosing
Run As -> Ant Build from the context menu. It could obviously be
run outside of the IDE if you have ANT installed on your path.
If you have any questions about this build, feel free to contact me
at patrick@rcpquickstart.com.
Modified by Lukas Zapletal <lzapletal@pikeelectronic.com>.
-->
<project name="com.pike.puma" default="build">
<property file="build.properties" />
<!--
PDE Build expects that the build directory contains a "plugins"
directory and a "features" directory. These directories should contain
the various plug-ins and features to be built.
It's possible to use the CVS checkout process that is built into
PDE Build. This is done with map files and is beyond the scope of
this tutorial.
This tutorial simply copies the projects directly from your workspace
into the appropriate build directory folders.
-->
<target name="init">
<mkdir dir="${buildDirectory}" />
<mkdir dir="${buildDirectory}/plugins" />
<mkdir dir="${buildDirectory}/features" />
<copy todir="${buildDirectory}/plugins">
<fileset dir="../">
<include name="**" />
</fileset>
</copy>
<copy todir="${buildDirectory}/features">
<fileset dir="../">
<include name="com.pike.puma.wm.feature/**" />
</fileset>
</copy>
</target>
<!--
This target actually executes the PDE Build process by launching the
Eclipse antRunner application.
-->
<target name="pde-build">
<echo message="Executing ${eclipseLocation}/plugins/org.eclipse.equinox.launcher_${equinoxLauncherPluginVersion}.jar"/>
<java classname="org.eclipse.equinox.launcher.Main" fork="true" failonerror="true">
<arg value="-application" />
<arg value="org.eclipse.ant.core.antRunner" />
<arg value="-buildfile" />
<arg value="${eclipseLocation}/plugins/org.eclipse.pde.build_${pdeBuildPluginVersion}/scripts/productBuild/productBuild.xml" />
<arg value="-Dtimestamp=${timestamp}" />
<classpath>
<pathelement location="${eclipseLocation}/plugins/org.eclipse.equinox.launcher_${equinoxLauncherPluginVersion}.jar" />
</classpath>
</java>
</target>
<target name="clean">
<delete dir="${buildDirectory}" />
</target>
<target name="build" depends="init, pde-build" />
</project>
Before we start the build process with Ant please test it under your Eclipse IDE. Click on your feature (or RCP app) project, select export and try to export for all platforms you are planning to automate. Do not forget to set your Target Platform to your RCP SDK with Delta Pack in your preferences.
If you are ready to build click on the build.xml and select Run as Ant. The Eclipse will initiate the build process. If something goes wrong go into build directory and see the log files.
Automating build process
I am pretty sure you want to run the build process automatically on your build server. Its easy - just install Apache Ant and issue "ant" command in your build project directory. The Apache Ant will read the main build.xml and spawns a new process (Eclipse Ant) that does the job. It is also possible to rewrite the main build Ant script to shell or windows batch but I prefer Ant - it is much more flexible and it runs on different platforms.
Summary
I showed very basic feature build that can be easily used for automating build process. It is good idea to adopt Martin Fowler's Continuious Integration and run tests periodically but this is out of space of this Knol. Please contact me for corrections or other additions.
This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which is available at http://www.eclipse.org/legal/epl-v10.html or (if you prefer) Creative Commons Attribution 3.0 License.






Setya
Invite as author
Untitled
Thanks for the article.
When I build my plugins this way I always encountered the following exception:
[javac] ----------
[javac] 1. ERROR in /home/setya/Projects
[javac] package com.farbeyond.core.e
[javac] ^
[javac] The type java.lang.Enum cannot be resolved. It is indirectly referenced from required .class files
[javac] ----------
[javac] 2. ERROR in /home/setya/Projects
[javac] package com.farbeyond.core.e
[javac] ^
[javac] The type Enum is not generic; it cannot be parameterized with arguments <FieldDisplay.Option
[javac] ----------
[javac] 2 problems (2 errors)
[javac] Compilation failed. Compiler errors are available in /home/setya/Projects
The java.home already points to JRE 1.6, I also have set all JRE setting I can think of to JRE 1.6.
Any ideas ?
Also, is it possible to automate build this way on a machine without Eclipse IDE installled ?
Regards,
Setya
have you set javacSource=1.6 and javacTarget=1.6 properly in your build.properties?
For automation you have to unpack Eclipse SDK. Its not able to use Eclipse build system without it.
EditSaveCancelDeleteDeleteBlock this userReport abusive commentHide report window
Hopefully this helps out other people who have the same problem.
In eclipse 3.5, you need to set the 'Compiler Options' section in your build.properties file.
Example:
J2SE-1.5=C:/Java/1.5
This will ensure that the specified version is used by the compiler. This got rid of the 'java lang Enum' not found problem.
You can also, lookup the PDE section in the Eclipse help.
Plug-in Development Environment Guide > Tasks > PDE Build Advanced Topics
Hope that helps
Baljeet
EditSaveCancelDeleteDeleteBlock this userReport abusive commentHide report window