Building an Eclipse RCP Product with Buckminster

Revision History
9 May 2013 Updated listings to reflect the git repository sources. Put a tip on using a mirror aggregated with b3.

In this tutorial I’ll show how to use Buckminster to build an Eclipse RCP Product, both in the IDE and headlessly (with ant). The application I’m building is the standard Eclipse Mail RCP example with the addition of Self-Update functionalities.

We will build two products configured with update sites; the first one will rely on standard Eclipse repositories for required features, while the second one will rely only on our own repositories.

The sources of this example can be found at http://sourceforge.net/p/buckyexamples/bucky-mail-rcp/?branch=ref%2Fmaster.

Motivations

There are some nice tutorials about building Eclipse RCP Products with Buckminster (such as, e.g., Ralf Ebert‘s, Code and Me‘s, and wiki pages).

However, I found these pages out-of-date in the sense that they use Indigo or Helios for building products; with Juno things are more complicated not due to Buckminster, but to new dependencies in Juno Eclipse features and bundles (for instance, org.eclipse.rcp internally depends on org.eclipse.emf.common and org.eclipse.emf.ecore) even if you do not use the new e4 application model; see for instance the dependencies in the screenshot

This means that you will have to deal with that in the target platform definition.

Furthermore, due to the way p2 repositories are built, you will soon get the dreaded “java returned 13″ when using Buckminster to build an Eclipse product (which relies on the p2 director actually), due to the above mentioned dependencies. Even for simple products like the Eclipse RCP Mail application… you can imagine when products are bigger ;) By the way, you get similar problems even if you try to use the standard Eclipse Product export wizard.

In this post I’ll detail my experience in dealing with these problems by using Buckminster and Eclipse standard mechanisms for dealing (automatically) with dependencies; similarly, I’m not using standard Target platform definitions (which again have problems if you want to build for multiple architectures), but I’m using the nice Buckminster materialization features for materializing the target platform. The same techniques can be used with much more complex products to build them without problems due to dependencies and required software.

The tutorial is quite long since I’ll also try to provide some explanations to the problems you have when building products (in general I guess) – although the explanations are not necessary, I think they might be useful to understand things better about features, bundles, products and p2.

Materializing the Target Platform

First of all, you need to install Buckminster in your Eclipse, using this repository

http://download.eclipse.org/tools/buckminster/updates-4.2

you will need only the features shown in the screenshot

Then, we need to create a project which with all our releng functionalities; this will be a general Eclipse project, with a Buckminster Component Specification (CSPEC); this CSPEC basically declares the target platform features as dependencies. The reasons why I’m not using a standard Eclipse Target platform definition can be found in my other post, in the section “Why not the Target Editor?”; they can be summarized with the fact that, with this technique you can get a target platform for building for multiple platforms and with all the required software automatically.

We call this releng project org.eclipse.buckminster.examples.rcp.mail.releng and the buckminster.cspec looks like this (we will enrich this cspec later to perform headless builds):

<?xml version="1.0" encoding="UTF-8"?><cs:cspec xmlns:cs="http://www.eclipse.org/buckminster/CSpec-1.0" 
         name="org.eclipse.buckminster.examples.rcp.mail.releng" 
         componentType="buckminster" version="1.0.0">
    <cs:dependencies>
        <cs:dependency name="org.eclipse.equinox.executable" componentType="eclipse.feature"/>
        <cs:dependency name="org.eclipse.equinox.p2.user.ui" componentType="eclipse.feature"/>
        <cs:dependency name="org.eclipse.rcp" componentType="eclipse.feature"/>
        <cs:dependency name="org.eclipse.rcp.source" componentType="eclipse.feature"/>
    </cs:dependencies>
</cs:cspec>

We basically want a target paltform with org.eclipse.rcp (and its sources, since they are useful when developing), org.eclipse.equinox.executable to build executable applications, and org.eclipse.equinox.p2.user.ui to enable the p2 update manager in our RCP application.

Then, we define a Resource Map (RMAP) which tells Buckminster where to find these dependencies; we will use of course official Eclipse p2 site repositories for these dependencies; we store this map into a file build.rmap:

<?xml version="1.0" encoding="UTF-8"?>
<rm:rmap xmlns:rm="http://www.eclipse.org/buckminster/RMap-1.0"
	xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0">
<?xml version="1.0" encoding="UTF-8"?>
<rm:rmap xmlns:rm="http://www.eclipse.org/buckminster/RMap-1.0"
	xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0">

	<rm:property key="projects.location" value="${workspace.root}" />
	<rm:property key="eclipse.download" value="http://download.eclipse.org" />
	<rm:property key="eclipse.target.platform" value="${eclipse.download}/releases/juno" />

	<rm:locator pattern="^org\.eclipse\.buckminster\.examples\.rcp\.mail(?:\..+)?$"
		searchPathRef="localsources" />

	<rm:locator searchPathRef="eclipse" />

	<rm:searchPath name="eclipse">
		<rm:provider componentTypes="eclipse.feature,osgi.bundle"
			readerType="p2" source="false" mutable="false">
			<rm:property key="buckminster.source" value="false" />
			<rm:property key="buckminster.mutable" value="false" />
			<rm:uri format="{0}">
				<bc:propertyRef key="eclipse.target.platform" />
			</rm:uri>
		</rm:provider>
	</rm:searchPath>
	<rm:searchPath name="localsources">
		<rm:provider componentTypes="eclipse.feature,osgi.bundle,buckminster"
			readerType="local" mutable="false">
			<rm:uri format="{0}/{1}">
				<bc:propertyRef key="projects.location" />
				<bc:propertyRef key="buckminster.component" />
			</rm:uri>
		</rm:provider>
	</rm:searchPath>

</rm:rmap>

This basically tells Buckminster to take

  • all the components with name which starts with org.eclipse.buckminster.examples.rcp.mail (which will be used for all our bundles and features in this example) from the local hard disk
  • and everything else from the main Juno releases repository.

Now, we define a Component Query (CQUERY) which materializes this very component; when Buckminster resolves a component if first, transitively, resolves all its dependencies; thus resolving our releng component corresponds to materialize our target platform. The build.cquery looks like this (note the reference to the build.rmap we wrote above):

<?xml version="1.0" encoding="UTF-8"?><cq:componentQuery xmlns:cq="http://www.eclipse.org/buckminster/CQuery-1.0" 
            resourceMap="build.rmap">
    <cq:rootRequest name="org.eclipse.buckminster.examples.rcp.mail.releng" componentType="buckminster"/>
    <cq:property key="target.arch" value="*"/>
    <cq:property key="target.os" value="*"/>
    <cq:property key="target.ws" value="*"/>
    <cq:advisorNode namePattern=".*" useTargetPlatform="false"/>
</cq:componentQuery>

Before starting the materialization, it is better to start from a plain and empty target platform (just like you do with a standard target definition with the target editor); one nice way of doing this, as illustrated also here, is

  1. Create a new general project named TP (or some name of your preference) in the workspace
  2. In “Window” => “Preferences” => “Plug-in Development” => “Target Platform”
    Select Add…
  3. Start with an empty target definition
  4. Enter TP in the Name: field (or some name of your preference)
  5. Add a directory
  6. Click on “Variables…” scroll down and select “workspace_loc” and then type TP in the Argument: field
  7. Press “Ok” and “Finish” twice, and
  8. set this as the active platform

With the build.cquery opened in Component Query Editor, we can start the materialization by pressing “Resolve and Materialize”

This might take some time depending on your Network connection.

(TIP: you may want to aggregate a local mirror using Eclipse b3; the aggregator file for the mirror is in aggregator/target-platform-mirror.b3aggr ; you can aggregate the mirror from Eclipse, after installing b3, or headlessly using the target “b3_aggregation” of build.ant. Then, you can use the build-local.cquery you find in the releng project in the git repository; see also the README.txt file you find in the releng project).

When the materialization finishes you find the target platform in the TP project in your workspace (if you followed the instructions above).

TIP: after a materialization of the target platform, it might be better to restart Eclipse, since sometimes Buckminster tends not to catch up correctly with the new target platform.

Creating our mail projects

We now create the bundle for our RCP application, using the Eclipse wizard and the RCP Mail template; this part is standard so I will not detail it here: org.eclipse.buckminster.examples.rcp.mail.bundle contains the RCP Mail bundle created with the wizard, and appropriately modified in order to enable the same update UI functionalities used in the SDK inside our RCP app (this is illustrated in this wiki page, the modifications to ApplicationWorkbenchWindowAdvisor and ApplicationActionBarAdvisor are marked in the code with ‘XXX’ task tags). We also create org.eclipse.buckminster.examples.rcp.mail.optional.bundle which contains an optional menu (and toolbar button).

We then create the feature project org.eclipse.buckminster.examples.rcp.mail.product.feature which contains our product definition:

  1. In this project we create a new product definition, mail.product, based on features (make sure that there is no <plugins> section in your feature-based product: open mail.product with the Text editor and delete the <plugins> section if found)
  2. Give the product an ID (which must be different from the ID of the containing feature), org.eclipse.buckminster.examples.rcp.mail.product
  3. In the Product definition section choose the Product org.eclipse.buckminster.examples.rcp.mail.bundle.product from Application org.eclipse.buckminster.examples.rcp.mail.bundle.application (don’t get confused by the term ‘product’ which is overloaded in this context: it is used both for the org.eclipse.core.runtime.products extension point, and for the product configuration which will be used to create the final product :)

In the Dependencies tab, add as the only dependency the feature we are in, org.eclipse.buckminster.examples.rcp.mail.product.feature. (We also do some branding and customizations, but they’re not interesting in this context).

Now, we have to “fill” the feature.xml of org.eclipse.buckminster.examples.rcp.mail.product.feature, keeping in mind that what’s in this feature will make our final product. Thus we add:

  • org.eclipse.buckminster.examples.rcp.mail.bundle, in the plug-in section, for our Mail RCP application
  • org.eclipse.rcp, as included feature, required to build an RCP product
  • org.eclipse.equinox.p2.user.ui, as included feature, to enable the p2 update manager in our RCP application
  • Note that org.eclipse.buckminster.examples.rcp.mail.optional.bundle is NOT part of product.feature, since this is meant to represent an optional functionality that can be installed later

product.feature.plugins product.feature.features

We can create a launch configuration (Eclipse Application) by selecting our product, and then select only our feature org.eclipse.buckminster.examples.rcp.mail.product.feature and then press “Select Required”.

mail-product-launch1 mail-product-launch2

The mail application should like this (note the Preferences menu and the Update functionalities)

mail-application-running

In org.eclipse.buckminster.examples.rcp.mail.product.feature we also add a touchpoint advice file p2.inf (See the online help for more details) to configure the repositories (update sites) that should initially be present in the application:

instructions.configure=org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/updates/,type:0,name:Buckminster Mail RCP Example Site,enabled:true); \
  org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/updates/,type:1,name:Buckminster Mail RCP Example Site,enabled:true); \
  org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//download.eclipse.org/releases/juno/,type:0,name:Juno,enabled:true); \
  org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//download.eclipse.org/releases/juno/,type:1,name:Juno,enabled:true); \
  org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//download.eclipse.org/tools/orbit/downloads/drops/R20120526062928/repository/,type:0,name:Orbit,enabled:true); \
  org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//download.eclipse.org/tools/orbit/downloads/drops/R20120526062928/repository/,type:1,name:Orbit,enabled:true);

We add the Juno release repository, the Orbit repository (not required, but just as a demonstration), and the repository on Sourceforge, where we deploy our p2 repository for our application (see the next section).

This file will be used during product build (see later).

Build a p2 Repository for our application

To build an update site (in the new terminology, “p2 repository”) for our product feature, we create a new feature project, org.eclipse.buckminster.examples.rcp.mail.product.site, and in the feature.xml we include our product feature (org.eclipse.buckminster.examples.rcp.mail.product.feature); we also create org.eclipse.buckminster.examples.rcp.mail.optional.feature (which includes org.eclipse.buckminster.examples.rcp.mail.optional.bundle) and we also include this feature in product.site; this way, once the repository is deployed, the optional functionalities can be installed in an existing mail application.

Since we’d like to have a category for our features, we add a category.xml file like the following one:

<?xml version="1.0" encoding="UTF-8"?>
<site>
   <feature id="org.eclipse.buckminster.examples.rcp.mail.product.feature">
      <category name="mail.category"/>
   </feature>
   <feature id="org.eclipse.buckminster.examples.rcp.mail.optional.feature">
      <category name="mail.category"/>
   </feature>
   <category-def name="mail.category" label="Buckminster Mail RCP Example">
      <description>
         Buckminster Mail RCP Example
      </description>
   </category-def>
</site>

Remember: when building the site.p2 on a feature project with Buckminster, you will build a p2 repository NOT for the very feature, but for the included features.

Before creating the repository we use a properties file like the following to specify additional parameters for the repository creation:

# This can be used only to build a site.p2, not a product
# since we can only build a site for multiple architectures

# Where all the output should go
buckminster.output.root=${user.home}/tmp/mail/buckminster.output
# Where the temp files should go
buckminster.temp.root=${user.home}/tmp/mail/buckminster.temp
# How .qualifier in versions should be replaced
# get the build timestamp instead of time of last modified resource
qualifier.replacement.*=generator:lastModified
generator.lastModified.format='v'yyyyMMdd-HHmm

# alternative: get the build timestamp instead of time of last modified resource
# qualifier.replacement.*=generator:buildTimestamp
# generator.buildTimestamp.format='v'yyyyMMdd-HHmm

# don't build source bundles and features
cbi.include.source=false

target.os=*
target.ws=*
target.arch=*

these properties specify:

  • the output directory
  • how the .qualifier in bundles and features version is replaced (in this example we replace it with a timestamp of the latest changed resource, with some formatting)
  • by default, Buckminster will generate also source features and source bundles when creating the p2 repository, but for a product it might not make sense to make sources installable, thus we disable the generation of sources
  • we create a repository for all supported architectures and operating systems

We can now run on this project the site.p2 Buckminster action: right click on the feature project => Buckminster => Invoke Action…, select the properties file above and select site.p2.

site.p2.action

The p2 repository will be generated (if you used the above properties file) into <your home>/tmp/mail/buckminster.output/org.eclipse.buckminster.examples.rcp.mail.product.site_1.0.0-eclipse.feature/site.p2 ; you can test your newly created repository by using the Install New Software dialog in a running Eclipse, specifying the complete local path of the created site.p2

produc.site.contents

The generated repository can then deployed to a remote site (in our example we deploy it to Sourceforge where we host also this tutorial code: http://master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/updates (if you want to browse it, use http://sourceforge.net/projects/buckyexamples/files/bucky-mail-rcp/updates/).

Building the product

Buckminster does not provide direct means to build a product, since it relies on the standard Eclipse org.eclipse.equinox.p2.director application, you just need to set up a few more files, with pretty standard contents.

Small digression about the p2 director

I think it might be worthwhile to know a few basic things about how the Eclipse p2 director application works to understand what follows (you can also using it for doing cool things like installing features into your eclipse installations from the command line).

If you provide the director application with

  • a repository (or a list of repositories separated by commas),
  • the ID of an installable unit,
  • a profile,
  • the architecture details
  • and a destination folder,

the director will create/install (provision) in that destination folder the requested product.

For instance, try to run the following command, replacing the path of your eclipse executable (in Windows you should use the command line version, eclipsec.exe), the destination path and the architecture details for your system

</path/to/your/eclipse/executable> -noSplash
   -application org.eclipse.equinox.p2.director
   -repository http://download.eclipse.org/releases/kepler
   -installIU org.eclipse.sdk.ide
   -tag InitialState
   -destination <destination path>
   -profile SDKProfile
   -profileProperties org.eclipse.update.install.features=true
   -p2.os linux
   -p2.ws gtk
   -p2.arch x86_64

and you’ll get a brand new Eclipse SDK from the Kepler site.

So what we will do to build our product is

  1. first create a p2 repository with all the features and bundles needed by our RCP application
  2. and then run the p2 director with appropriate arguments (relying on the p2 repository we created).

Setting up a project for building the product

Since we have already a feature project for building the p2 repository, org.eclipse.buckminster.examples.rcp.mail.product.site, we will use it also for building the product.

Inside this project we create a folder (build) with the following product.ant file which calls the p2.director ant task (in the following we will provide also some explanations):

<project name="Product packaging">

    <target name="create.product">

        <property name="product.install.directory" location="${sp:destination}" />
        <delete dir="${product.install.directory}" includeemptydirs="true" failonerror="false" />
        <mkdir dir="${product.install.directory}" />
        <buckminster.valuepath value="${fs:repositories}" id="repositories.valuepath" />
        <pathconvert 
                pathsep="," 
                targetos="unix"
                property="product.repositories" 
                refid="repositories.valuepath">
            <map from="" to="file:/" />
        </pathconvert>
        <echoproperties />
        <echo message="Repositories: ${product.repositories}" />
        <echo message="Install Dir : ${product.install.directory}" />

        <p2.director 
            destination="${product.install.directory}" 
            metadataRepository="${product.repositories}" 
            artifactRepository="${product.repositories}" 
            profile="${profile}" 
            arch="${target.arch}" 
            os="${target.os}" 
            ws="${target.ws}" 
            roaming="true" 
            extraarguments="-profileProperties org.eclipse.update.install.features=true">
            <iu id="${iu}" />
        </p2.director>
    </target>
</project>

For each plugin and feature projects Buckminster automatically infers a Component Specification (you can view that by right clicking on the project => Buckminster => View CSpec…) with its standard actions; we must extend this specification with additional actions to create the product, creating inside our feature project a buckminster.cspex file (note cspex, with the final x instead of c):

<?xml version="1.0" encoding="UTF-8"?>
<cspecExtension xmlns:com="http://www.eclipse.org/buckminster/Common-1.0"
                    xmlns="http://www.eclipse.org/buckminster/CSpec-1.0">
    <actions>
        <public name="create.product" actor="ant">
            <actorProperties>
                <property key="buildFile" value="build/product.ant" />
                <property key="targets" value="create.product" />
            </actorProperties>
            <properties>
                <property key="profile" value="BuckyRcpMailProfile" />
                <property key="iu" value="org.eclipse.buckminster.examples.rcp.mail.product" />
            </properties>
            <prerequisites alias="repositories">
                <attribute name="site.p2" />
            </prerequisites>
            <products alias="destination" base="${buckminster.output}">
                <path path="BuckyRcpMail.${target.ws}.${target.os}.${target.arch}/" />
            </products>
        </public>
        <public name="create.product.zip" actor="ant">
            <actorProperties>
                <property key="buildFileId" value="buckminster.pdetasks" />
                <property key="targets" value="create.zip" />
            </actorProperties>
            <prerequisites alias="action.requirements">
                <attribute name="create.product" />
            </prerequisites>
            <products alias="action.output" base="${buckminster.output}">
                <path path="BuckyRcpMail.${target.ws}.${target.os}.${target.arch}.zip" />
            </products>
        </public>
    </actions>
</cspecExtension>

This cspex extends the default actions of our feature projects with the new actions create.product and create.product.zip; note that the latter depends on the former and simply creates a zip of the directory containing the generated product. The create.product action calls the ant task with the same name in product.ant passing the profile and the IU of our product configuration, i.e., the one we chose above during the creation of product configuration, org.eclipse.buckminster.examples.rcp.mail.product in our example (this is the value we inserted for the field ID in the “General Information” section of the product configuration editor).

The action create.product has as prerequisite the (standard Buckminster) action site.p2 (since the component name is not specified, the component we are in is assumed); the alias of site.p2 action, repositories, will be passed to the product.ant; indeed, what is being passed to the ant file is the path resulting from site.p2, in the shape of fs:repositories, which is a path group (you can read more in the Eclipse Buckminster, The Definitive Guide, Section “Access to prerequisites and product locations” – in product.ant, we extract the actual path and do some conversion for Windows backslashes so that we obtain a valid URL for the director). We also pass a name for the profile of our product, the operating system details and the destination.

Summarizing, the steps to create the product with the p2 director are:

  1. create a p2 repository for this feature (actually, for the features and bundles included in this feature)
  2. run the director application specifying our product identifier as the installable unit, and the above created p2 repository (together with the other parameters for the director)

Before running the create.product action in the IDE we must specify a property file (similar to the one we used for mail.site project): creating the product will not work with * for os/ws/arch, because you can create the product only for a specific platform at time. For instance, this is the one I use for my Linux system

# Where all the output should go
buckminster.output.root=${user.home}/tmp/mail/buckminster.output
# Where the temp files should go
buckminster.temp.root=${user.home}/tmp/mail/buckminster.temp
# How .qualifier in versions should be replaced
qualifier.replacement.*=generator:lastModified
generator.lastModified.format='v'yyyyMMdd-HHmm

# don't build source bundles and features
cbi.include.source=false

target.os=linux
target.ws=gtk
target.arch=x86_64

In the sources of this tutorial, you can find property files for most common configurations.

You can then right click on org.eclipse.buckminster.examples.rcp.mail.product.site, select the create.product action, and the property file for the architecture you want to build your product for

create.product.action

In the console view you can see that first the site.p2 for the current feature project is created and then the director is called to install the product… but… you get this error:

[ant] Cannot complete the install because one or more required items could not be found.
[ant] Software being installed: Mail RCP Product 1.0.0.qualifier 
(org.eclipse.buckminster.examples.rcp.mail.product 1.0.0.qualifier)
[ant] Missing requirement: 
Eclipse e4 Rich Client Platform 1.1.0.v20120521-2329-8yFTIGIbGGduEZ6-7-jLx41nXj 
(org.eclipse.e4.rcp.feature.group 1.1.0.v20120521-2329-8yFTIGIbGGduEZ6-7-jLx41nXj) 
requires 'org.eclipse.emf.common.feature.group [2.7.0,3.0.0)' 
but it could not be found
[ant] Cannot satisfy dependency:
[ant] A problem occured while invoking the director.

To understand what is going on, let’s do another digression

Small digression about the p2 publisher

When a p2 repository is generated for a feature, the repository will contain:

  • the included features (the tab “Included Features” in the feature editor)
  • the plug-ins and fragments (the tab “Plug-ins” in the feature editor)
  • but NOT the required software (required features and required bundles)

The required plug-ins and features can be made explicit in the “Dependencies” tab in the feature editor; even if they are not specified, the dependencies are computed automatically and they are still needed by the director when the product is installed.

Since these dependencies will not be part of the generated p2 repository, we get an error when installing the product…

Back to our product building

In our case we get an error about the feature org.eclipse.emf.common which is required by org.eclipse.e4.rcp. The feature org.eclipse.rcp (which is included in our product.feature) INCLUDES org.eclipse.e4.rcp, but org.eclipse.e4.rcp REQUIRES (not includes) org.eclipse.emf.common (and also org.eclipse.emf.ecore):

e4.rcp.deps

Thus, org.eclipse.emf.common will be not present in the generated p2 repository and the installation fails. With Indigo, this problem was not experienced, since org.eclipse.rcp was self-contained (and indeed, Ralf Ebert’s tutorial did not experience this problem). You would experience similar problems if your product is more involved than the simple Mail example application and requires more features and bundles: in that case the dependencies are much more.

In the following, I’ll describe 3 possible solutions to deal with that. The third one is (in my humble opinion) the best one, and is the one I’ll use in this tutorial.

Pass additional repositories to the director

We can pass the director (in our case we must modify the product.ant) additional p2 repositories, i.e., the ones we used in the RMAP, that we used to materialize the target platform (in our example the Juno release repository and the Orbit repository).

The drawbacks of this approach is that you depend on remote sites each time you build the products (you can use local mirrors though) and most of all, you do not have control on what is taken from which repository, i.e., you do not have the same control you had when defining the target platform; thus, you risk to build a product which does not use the same things of your target platform. This is especially true when building complex products with a complex target platform taking different software from several different repositories.

Fix the feature manually with missing requirements

You can add as included features into your product.site feature project (NOT the product.feature project) the missing features one by one; this way, when the site.p2 is built the required features will go there as well, and the director will find them when installing the product.

There will surely be more than one missing feature, and the director will issue an error only on the first missing feature; thus, it will take some time to include them all.

Furthermore, including features will not be enough: you will surely have to add also bundles (plug-ins and possible fragments) to your product.site feature. For instance, org.eclipse.equinox.p2.user.ui (the one we added to our product to handle update functionalities) includes the plug-in org.eclipse.equinox.p2.ui.importexport,

p2.user.ui.bundles

which depends (i.e., requires, not includes) the bundle org.eclipse.ui.forms,

p2.ui.importexport.deps

which, again, will not be part of our site.p2 unless explicitly added as a bundle!

Thus, it will take some time to have a site.p2 that makes the director happy ;)

Finally, I think that having all the dependencies hardcoded in the feature.xml makes the project highly coupled with that specific target environment (in Indigo the additional software might not even be available, in Kepler new requirements might have to be added)… why should I deal with dependencies myself?

Provision your target platform as a p2 repository

The idea is to have a p2 repository which contains EVERY feature and bundle of our current target platform (the one we materialized at the beginning); I had blogged about a manual technique, but I like to avoid manual solutions (for maintainability and portability reasons) and prefer automatic ones.

Indeed, all the features and bundles for your products are in your target platform (otherwise your bundles would not compile, or your product launch would not work); yes, even the ones you were not aware of, like org.eclipse.emf.common and org.eclipse.emf.ecore, since Buckminster has materialized them for you as dependencies of org.eclipse.rcp. We just need a way to create a p2 repository from the current target platform.

There is a p2 ant task for this, p2.publish.featuresAndBundles, which publishes metadata for pre-existing binary features and plug-ins. All we need to do is:

  • modify product.ant with a target which invokes p2.publish.featuresAndBundles with all the arguments, in particular, the current target platform as the source to create the p2 repository (we get its location using a Buckminster property):
<project name="Product packaging">

	<target name="create.product">
                 ... as before ...
	</target>

	<target name="create.target.platform.repository">
		<buckminster.targetPlatformLocation property="target.platform.location" />
		<property name="target.platform.repository" value="file:/${sp:output}" />
		<property name="repository.name" value="Target Platform Repository" />		
		<p2.publish.featuresAndBundles 
			repository="${target.platform.repository}" 
			repositoryName="${repository.name}" 
			source="${target.platform.location}" 
			publishArtifacts="true" />
		<buckminster.publishJRE metadataRepository="${target.platform.repository}" publishArtifacts="false" />
	</target>
</project>
  • add an action, site.tp, in buckminster.cspex that invokes the above ant target (the action could be made private, but in case you want to run it manually to do some tests we make it public); note that we give the repository of the target platform a name since we also deploy it as we will show later. Then, the action create.product will have as a prerequisite also the site.tp action, besides site.p2:
<public name="create.product" actor="ant">
    <actorProperties>
        <property key="buildFile" value="build/product.ant" />
        <property key="targets" value="create.product" />
    </actorProperties>
    <properties>
        <property key="profile" value="BuckyRcpMailProfile" />
        <property key="iu"
            value="org.eclipse.buckminster.examples.rcp.mail.product" />
    </properties>
    <prerequisites alias="repositories">
        <attribute name="site.p2" />
        <attribute name="site.tp" />
    </prerequisites>
    <products alias="destination" base="${buckminster.output}">
        <path path="BuckyRcpMail.${target.ws}.${target.os}.${target.arch}/" />
    </products>
</public>

...

<public name="site.tp" actor="ant">
	<actorProperties>
		<property key="buildFile" value="build/product.ant" />
		<property key="targets" value="create.target.platform.repository" />
	</actorProperties>
	<properties>
		<property key="repository.name" value="Buckminster Mail RCP Example Platform Site" />
	</properties>
	<products alias="output" base="${buckminster.output}/site.tp/" />
</public>

The repository for the target platform will be generated in the directory site.tp.

Now, if we run the create.product action again, the director will be provided both with the p2 repository of our product and the p2 repository of the target platform, and the director will be able to find everything it needs to install the product.

You should get no error now, and you can find your product ready to run in the output directory; if you used the properties file above, depending on the chosen architecture and OS, you will find the product in <your home>/tmp/mail/buckminster.output/org.eclipse.buckminster.examples.rcp.mail.product.site_1.0.0-eclipse.feature/BuckyRcpMail.<ws>.<os>.<arch> .

Deploying your sites

We have already seen that we can deploy our product.site on the net (in our case, it’s here); however, this will still require additional Eclipse repositories (for required software which is not part of our product repository). If this reminds you of the same issue we had when building the product you’re on the right track ;)

The site.tp was useful to build our product, but we could also deploy it on the Internet, http://master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/cloud-updates (if you want to browse it, use http://sourceforge.net/projects/buckyexamples/files/bucky-mail-rcp/cloud-updates/), together with our site.p2 to make our product independent from other repositories.

To show our “independence” we create another product, a “cloud” version, where the preconfigured update sites are only the ones we maintain: we create org.eclipse.buckminster.examples.rcp.mail.cloud.product.feature, which is basically the same as org.eclipse.buckminster.examples.rcp.mail.product.feature, with another product configuration, another product identifier and another touchpoint advice file p2.inf with only our mantained repositories (i.e., the standard update site, site.p2, and the cloud-updates, which is the one we get from the target platform, site.tp):

instructions.configure=org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/updates/,type:0,name:Buckminster Mail RCP Example Site,enabled:true); \
  org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/updates/,type:1,name:Buckminster Mail RCP Example Site,enabled:true); \
  org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/cloud-updates/,type:0,name:Buckminster Mail RCP Example Platform Site,enabled:true); \
  org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/cloud-updates/,type:1,name:Buckminster Mail RCP Example Platform Site,enabled:true);

To deal with this product we have additional dedicated actions in the .cspex file of product.site (see the original source), namely create.cloud.product and create.cloud.product.zip, which basically rely on the same product.ant’s create.product target passing a different profile name and a different product UI.

You can also try to install our product from the command line, using the deployed remote repositories, with the same technique we showed for installing the Eclipse SDK from the command line; you just need to use one of the two product identifiers org.eclipse.buckminster.examples.rcp.mail.product or org.eclipse.buckminster.examples.rcp.mail.cloud.product, specify the path of your eclipse executable (in Windows you should use the command line version, eclipsec.exe), the destination path and the architecture details for your system, here are some examples: the first one installs the mail product for Linux 64bit, the second one installs the mail cloud product for Windows 64bit

<your/eclipse/dir>/eclipse -noSplash \
-application org.eclipse.equinox.p2.director \
-repository \

http://master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/updates,\

http://master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/cloud-updates \
-installIU org.eclipse.buckminster.examples.rcp.mail.product \
-tag InitialState \
-destination <your/destination> \
-profile MailProfile \
-profileProperties org.eclipse.update.install.features=true \
-p2.os linux \
-p2.ws gtk \
-p2.arch x86_64
<your/eclipse/dir>/eclipse -noSplash \
-application org.eclipse.equinox.p2.director \
-repository \

http://master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/updates,\

http://master.dl.sourceforge.net/project/buckyexamples/bucky-mail-rcp/cloud-updates \
-installIU org.eclipse.buckminster.examples.rcp.mail.cloud.product \
-tag InitialState \
-destination <your/destination> \
-profile MailCloudProfile \
-profileProperties org.eclipse.update.install.features=true \
-p2.os win32 \
-p2.ws win32 \
-p2.arch x86_64

NOTE: there will be redundancies in the deployed repositories since some features and bundles are contained both in site.p2 and site.tp; but this is just a tutorial example (and they do not disturb the installation/updates): it is up to you to choose what to deploy and how to aggregate them, in case.

Building Headlessly

For continuous integration, but also for having an automated headless way to build the products for multiple architectures and build the p2 repositories with only one click, it is very useful to have an Ant script that does all of the above. The build.ant is stored in the project org.eclipse.buckminster.examples.rcp.mail.releng, and it relies on the common.ant file which does most of the work. The Ant script relies on Buckminster headless; I won’t detail here how to install Buckminster headless, also because the Ant script checks whether it is already installed in your computer, and if it is not, it will install it for you :-) (it first installs Buckminster director whose zip file is in the tools subdirectory of the releng project). In the launches directory of the releng project you also find some launch configurations to experiment with.

Buckminster headless will need a way of importing the projects into the headless workspace to build them; the build.cquery we already described can be used to materialize in the workspace the releng project, but then the buckminster.cspec needs to be modified in order to materialize also the other projects. We just need to add dependencies to projects which depend on all of the other projects (since Buckminster will automatically materialize all dependencies). The feature project org.eclipse.buckminster.examples.rcp.mail.product.site depends on all the other ones. So we add this dependency (the rmap already provides all the locators for materializing all our projects). The final buckminster.cspec looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<cs:cspec xmlns:cs="http://www.eclipse.org/buckminster/CSpec-1.0" name="org.eclipse.buckminster.examples.rcp.mail.releng" componentType="buckminster" version="1.0.0">
    <cs:dependencies>
        <cs:dependency name="org.eclipse.buckminster.examples.rcp.mail.product.site" componentType="eclipse.feature"/>
        <cs:dependency name="org.eclipse.equinox.executable" componentType="eclipse.feature"/>
        <cs:dependency name="org.eclipse.equinox.p2.user.ui" componentType="eclipse.feature"/>
        <cs:dependency name="org.eclipse.rcp" componentType="eclipse.feature"/>
        <cs:dependency name="org.eclipse.rcp.source" componentType="eclipse.feature"/>
    </cs:dependencies>
</cs:cspec>

The build.ant script then invokes Buckminster headless with two text files containing the headless commands: headless-resolve-commands.txt to materialize all the projects and the target platform (by resolving build.cquery)

setpref targetPlatformPath="${target.platform}"
resolve "${projects.location}/org.eclipse.buckminster.examples.rcp.mail.releng/build.cquery"

and headless-perform-commands.txt which performs all the actions to build what we want.

build

# build the site for installing the product, i.e., mail feature and platform feature
# IMPORTANT: build the site first for all architectures, so that we can create
# products for multiple architectures
perform -D target.os=* -D target.ws=* -D target.arch=* org.eclipse.buckminster.examples.rcp.mail.product.site#site.p2

# now build the products and zip them
perform -D target.os=linux -D target.ws=gtk -D target.arch=x86_64 org.eclipse.buckminster.examples.rcp.mail.product.site#create.product.zip
perform -D target.os=linux -D target.ws=gtk -D target.arch=x86 org.eclipse.buckminster.examples.rcp.mail.product.site#create.product.zip
perform -D target.os=win32 -D target.ws=win32 -D target.arch=x86_64 org.eclipse.buckminster.examples.rcp.mail.product.site#create.product.zip
perform -D target.os=win32 -D target.ws=win32 -D target.arch=x86 org.eclipse.buckminster.examples.rcp.mail.product.site#create.product.zip
perform -D target.os=macosx -D target.ws=cocoa -D target.arch=x86 org.eclipse.buckminster.examples.rcp.mail.product.site#create.product.zip
perform -D target.os=macosx -D target.ws=cocoa -D target.arch=x86_64 org.eclipse.buckminster.examples.rcp.mail.product.site#create.product.zip

# now build the cloud products and zip them
perform -D target.os=linux -D target.ws=gtk -D target.arch=x86_64 org.eclipse.buckminster.examples.rcp.mail.product.site#create.cloud.product.zip
perform -D target.os=linux -D target.ws=gtk -D target.arch=x86 org.eclipse.buckminster.examples.rcp.mail.product.site#create.cloud.product.zip
perform -D target.os=win32 -D target.ws=win32 -D target.arch=x86_64 org.eclipse.buckminster.examples.rcp.mail.product.site#create.cloud.product.zip
perform -D target.os=win32 -D target.ws=win32 -D target.arch=x86 org.eclipse.buckminster.examples.rcp.mail.product.site#create.cloud.product.zip
perform -D target.os=macosx -D target.ws=cocoa -D target.arch=x86 org.eclipse.buckminster.examples.rcp.mail.product.site#create.cloud.product.zip
perform -D target.os=macosx -D target.ws=cocoa -D target.arch=x86_64 org.eclipse.buckminster.examples.rcp.mail.product.site#create.cloud.product.zip

Before building the products with the create.product actions (and zip them) it is crucial to first build the product.site repository for all platforms; this way, we will then be able to build products for several platforms (if you don’t do that, only the first product will have executable files).

All the output will be stored in the buildroot directory in the same root of our projects; the target platform will be materialized in the subdirectory target.platform, the repositories and the products can be found in the subdirectory buckminster.output (each of them in the subdirectories we saw before).

Try the example

You can find the packaged products on Sourceforge. Download the one for your system (either the standard version or the “cloud” version); you will see the preconfigured update sites. Try to update the application with Check for Updates (there should be an update available for the product) and to install the optional feature.

Conclusions

I hope you found this tutorial useful :)

With the techniques described here you should be able to build even complex products seamlessly without having to deal explicitly with dependencies which are already dealt with by Eclipse PDE and p2. Once the target platform is defined correctly (and you see that with Buckminster you can do that without having to worry about required software), everything will be built automatically and your projects (especially product definitions and feature definitions) will be clean and neat :)

Be Sociable, Share!

29 thoughts on “Building an Eclipse RCP Product with Buckminster

    1. Sam Su

      I am new to Eclipse + Buckminster and your blog has lots of details. However, I get stuck at the beginning of the step “Creating our mail projects”. It seems there is no wizard in Juno to create Mail RCP Project. Am I missing something?

      Thanks!

      –Sam

      Reply
      1. Lorenzo Bettini Post author

        Hi Sam
        You should create a Plug-in Project, give it a name, press next, and make sure to select “Would you like to create a rich client application”; then you are presented with some templates. If no template for rcp application is shown, then I guess you are not using an Eclipse with RCP SDK installed; you can either download “Eclipse for RCP and RAP Developers”, or install RCP SDK in your Eclipse.
        Please let me know whether this solves your problem.

        Reply
  1. Sam Su

    Mr. Bettini,

    Something interesting here. I am at the beginning of the step of “Build a p2 Repository for our application”. After right clicking on the product.site project => Buckminster => Invoke Action…, select the properties file and select site.p2, I got error:

    No component named org.hibernate.eclipse.libs:osgi.bundle$3.6.0.Final-v20130327-1513-B111 is known to Buckminster

    Then I check Eclipse’s preferences of “Target Platform”: it is set to “Running Platform(Active)”. I switch to “TP”, the one I created at the beginning of the tutorial. Now projects “org.eclipse.buckminster.examples.rcp.mail.bundle” and “org.eclipse.buckminster.examples.rcp.mail.optional.bundle” failed to compile. I proceed anyway with Buckminster and get the following error:

    The project was not built since its build path is incomplete. Cannot find the class file for org.eclipse.swt.widgets.Composite. Fix the build path then try building this project

    Then I switch back Eclipse’s preferences of “Target Platform” to “Running Platform(Active)”. try Buckminster again, get “No component named org.hibernate.eclipse.libs…” again. but the funny part is, if I keep trying Buckminster several times, I do get one successful build! And if I get one through, if I continue to try Buckminster, most of time it is ok. However, if I close Eclipse and restart, I got “No component named org.hibernate.eclipse.libs…” again! Sometimes, I get different error like “No component named org.eclipse.e4.core.services:osgi.bundle/[1.0.0.v20120521-2346,1.0.0.v20120521-2346] is known to Buckminster”. (BTW, I don’t see any dependency on hibernate at all in the projects of your tutorial. The successful built repo has no hibernate related jar file either.)

    Have you seen something like this? Is Buckminster really so mysterious/unstable?

    Thanks

    Sam

    Reply
    1. Lorenzo Bettini Post author

      Hi Sam

      First of all, are you using the sources from the git repository http://sourceforge.net/p/buckyexamples/bucky-mail-rcp/?branch=ref%2Fmaster ?
      Because the listings you find in this blog post might be outdated (sorry, my fault, I’ll update them to reflect the actual sources).

      If you run the site.p2 action you need to make sure that you are NOT using the “Running Platform”, but the “TP” you must have materialized in advanced. If you were using the Running Platform, then I guess you did not follow the step correctly :)

      I’ve just tried
      - to import in a clean workspace the sources from the git repository,
      - then I prepared the TP project and the corresponding target platform
      - I made sure that this new empty target platform is set as the current target platform
      - (after this of course the eclipse project won’t compile since the target platform is still empty, so lots of dependencies are missing)
      - then I resolved the cquery (takes some time to download all the dependencies for the target platform)
      - when this is finished, the projects in the workspace compile fine
      - then site.p2 works fine

      Again, please make sure to use the sources from the git repositories which are up-to-date

      Buckminster just works, but if you start messing with target platforms then it might get confused ;)

      the hibernate bundle is surely not part of the target platform that you materialize with the cquery, but it might be part of your current eclipse installation… but you must not use your eclipse installation as the target platform :)

      please, let me know about your progress!

      Lorenzo

      Reply
    2. Sam Su

      A quick update: I manage to finish the tutorial all to the end. This is a well-written tutorial with lots of insights. My goal is to have one of our projects headless built in Jenkins. With all the complexity involved in setting up Buckminster, now I am not sure I want to use it -:(

      I do have another question: what is the use of the TP project in this tutorial? Just to materialize the releng project? I cannot use it as “Target Platform” for Eclipse Preference. If I do use it as “Target Platform”, the bundle projects fail to build.

      Thanks again,

      Sam

      Reply
      1. Sam Su

        Sorry that I just saw your reply to my previous comment. I coded the project by following the tutorial. I will try to download from Git and start from a clean workspace. Thank you for your quick response!

        Reply
      2. Lorenzo Bettini Post author

        The TP project is used to materialize the target platform to build your bundles in your Eclipse workbench; it is a way to make sure to start with a really empty target platform. If, after the materialization, you cannot use it as the target platform then something is wrong in what you’ve done.

        If you materialize the releng project (after creating the TP project, the new empty target platform as explained, and make it active) the bundles and features for the target platform will be downloaded, and installed in the TP project.

        But as I said, make sure to use the sources from the git repository (again, apologies, I’ll update the listings in this blog post :) I see from your next reply that you did not use the git repositories, thus, this might be the causes of your problem.

        Note that the TP project is needed only when you build in Eclipse; headlessly, that is not required, since when materializing the target platform from a Jenkins job (or using the ant script) it will always start from an empty target platform.

        You’ll see that once you got familiar with these concepts building will be really easy! :)

        keep me posted about your progress.

        Reply
        1. Lorenzo Bettini Post author

          Sam, I updated the listings in the blog post to reflect the git repository sources :)

          Reply
          1. Sam Su

            Mr Bettini,

            I follow your instruction to start with a fresh installation of Eclipse Juno RCP and an empty workspace. Everything works. (I don’t do headless build this time.) I also download the git repo but I don’t import them into my workspace — what I did is to follow your tutorial and I am happy to see everything works as expected.

            Some minor suggestions:

            0. It is important to start with an empty workspace and fresh installation of JUNO RCP Eclipse.

            1. Remind the readers that they cannot edit the XML content of files build.cquery, build.rmap and buckminster.cspec directly inside Eclipse. The provided GUI editor for these files is kind of clumsy, like all GUI XML editors. I use external text editor.

            2. The displayed content for build.rmap has extra three lines at the beginning: xml, rmap

            3. in 3rd step of bulding project “TP”, the option is “Nothing: Start with an empty target definition”

            4. Maybe it is better to move the steps of creating the empty target platform (TP) to the very beninning of tutorial.

            5. in section “Build a p2 Repository for our application”, maybe it is better to re-phase the first paragraph to detail steps: 1). create future project org.eclipse.buckminster.examples.rcp.mail.optional.feature, in its feature.xml, add plugin “org.eclipse.buckminster.examples.rcp.mail.optional.bundle”; 2). create a feature project, org.eclipse.buckminster.examples.rcp.mail.product.site, and in the feature.xml, add product feature (org.eclipse.buckminster.examples.rcp.mail.product.feature) and optional feature (org.eclipse.buckminster.examples.rcp.mail.optional.feature)

            6. line “We can now run on this project the site.p2 Buckminster action: right click on the feature project” ==> “We can now run on this project the site.p2 Buckminster action: right click on the product.site project” to avoid confusion.

            Again, I think this is best tutorial I read! Thank you!

            Sam

            Reply
            1. Lorenzo Bettini Post author

              Sam, thanks a lot for you suggestions!
              I’ll try to apply them as soon as possible!

              Reply
  2. Vlad

    This was a great tutorial, thanks a lot!

    I have a small problem that I haven’t figured yet, maybe you can give me a quick hint: my features need to be built against Eclipse 3.7, but the standalone product should be based on 4.3. If i got it right I need to have two site.tp, but I haven’t figured out yet how to let buckminster which one to use.

    best regards,
    Vlad

    Reply
    1. Vlad

      Ah, I think I got it: I have to use a custom build.properties and set eclipse.target.platform, like your build-local does.

      /Vlad

      Reply
      1. Lorenzo Bettini Post author

        HI Vlad, sorry for the late reply

        I’m not sure I understand what you need to do…
        can you please elaborate that?
        As you described the problem, I do not think it is possible to do such build, but I may be wrong :)

        Reply
        1. Vlad

          Going on vacation has the effect of erasing memories, but I think that the way I did it was by running the build twice, once for the plugins and once for the product, each with a different target platform.

          Reply
          1. Lorenzo Bettini Post author

            OK, now I see :)
            you wanted to build a p2 repository for your plugins against a target platform, and you wanted to build the product against a different target platform.
            I thought you wanted to build a product where some plugins were built against a target platform and others against a different target platform :)

            Reply
  3. Vlad

    Hi! I hope you can help me with my builds, I am investigating but it’s slow as a build takes 20 minutes…

    I am building an IDE product and when I do it all in one run, everything is fine.

    Building a product is not needed every time, so I split the Ant task and the Jenkins job. The ones that assemble the product are using the p2 site generated by the previous step. The only projects materialized from sources are the product and product.site.

    The problem is that the director chokes, saying that my product IU is not available on the update site. But it is, which is proved by changing the line 30 in product.ant from to . Then the build proceeds and the products are created.

    Of course, there is a side effect: the generated products are missing the launcher executables, even when doing a “one run” build.

    Do you have any suggestion about where I should look? Thanks in advance!

    Reply
    1. Lorenzo Bettini Post author

      Hi Vlad, sorry for the late reply

      First of all, by “IDE product” do you mean that you are using org.eclipse.sdk?

      I cannot see the change in line 30 of product.ant; I think the wordpress editor removes the XML tags, so I do not understand what you change from and to.

      Can you manually install your product from the p2 site by calling the director from the command line?

      You say that your products still miss the executables… does that happen for all architectures? Have you built your p2 site for all os,arch,ws before running the director? Have you included the equinox executable feature in the target platform?

      Hope to hear from you soon
      Lorenzo

      Reply
      1. Vlad

        [Now I can post comments again]

        I am building a product based on the eclipse workbench, yes. It works all right when I am materializing all my projects from sources, no problems there.

        Maybe I’m doing it overly complicated.

        I have an org.erlide feature that contains my plugins and an org.erlide.site that has the Buckminster stuff to build the p2.site for it. Just regular plugins, no products.

        Then I have an org.erlide.product project that has the product specification and an org.erlide.product.site that handles building the p2.site for the product and the product itself.

        What I want to do is to build the plugins only once and when assembling the product refer to that update site just as if it’s part of the target platform. the product and product.site projects are materialized as sources.

        There seems to be a difference between how Buckminster handles artifacts materialized as sources from local provider and those materialized from a p2 site.

        Using the scripts that work when everything is materialized as sources, I get an error that the product can’t be found. If I change product.ant from [iu id="${iu}" /] to [iu id="${iu}.feature.group" /] then the product p2 site is generated and looks ok (didn’t try it, but metadata and plugins look fine), but without any executables. That’s for all platforms, and it’s the same script that builds fine in the first variant (only the rmap file is different)

        Thanks!
        best regards,
        Vlad

        Reply
        1. Vlad

          Aha, it looks that I couldn’t comment earlier because I had html tags. Not even using the html escapes did help. That’s why they were replaced with [] above.

          Reply
        2. Lorenzo Bettini Post author

          Hi Vlad,

          mh… that’s not what I see from the sources: your .product file (erlide.product) is in org.erlide.branding project, while org.erlide.product project does not contain any product configuration.

          Moreover, your erlide.product specifies as UID org.erlide.product which is exactly the same id of org.erlide.product project, which really messes up things.

          from what I know, the suggested way of doing things is to have a feature project say org.erlide.product.feature which contains the .product file; in the .product file you specify an UID different from any Eclipse project id, say org.erlide.product (note the differences between the uid and the feature project name). The product configuration is based on a single feature which is the feature it is in, that is org.erlide.product.feature. In the feature.xml you include all the features your product needs (including org.eclipse.rcp, the features for Eclipse IDE and org.erlide which I assume includes, in turn, all your stuff).

          That’s what I’ve seen around and what I’ve implemented in my blog post.

          Reply
          1. Vlad

            Just a quick question at the moment: do I need org.eclipse.rcp if I am building on org.eclipse.platform? From what I can say, the platform includes rcp.

            Reply
            1. Lorenzo Bettini Post author

              If you include org.eclipse.platform, which in turn includes org.eclipse.rcp, you should not need to include org.eclipse.rcp

              Reply
          2. Vlad

            Thank you very much for your input! I made the fixes you pointed out and it works now. There were some more details that were wrong, but the main source of confusion for me was that in product.site/buckminster.cspex, the “iu” property has to be the product id, not the feature id. This is thus one of the reasons that the two ids have to be different — couldn’t we have a warning or error from PDE or Buckminster instead of silent failure?

            [aside] The trouble with these things is that one doesn’t do them often enough so the one remembers the details the next time. Posts like yours help a lot, but it would be neater if there was a wizard that would put everything in place and guide configuration changes after that. [/aside]

            Thanks again!

            Reply
            1. Lorenzo Bettini Post author

              Great! :)
              As far as I remember the PDE editor for the .product file issues a warning when you use the same identifier for the product and for the project, but probably only when the .product file is in the same project, while in your case it was in a different project, that’s why you probably did not get any warning.
              As for the wizard, I agree! I was also thinking on working on such a wizard :)

              Reply
  4. Philip

    Firstly, Great tutorial.

    When I use your git remote uri I get the following error ->
    Git repository path “git://git.code.sf.net/p/buckyexamples/bucky-mail-rcp” is not absolute

    Reply
    1. Lorenzo Bettini Post author

      Philip, I’m glad you liked it :)

      Concerning the error you mention: who shows this example? When you clone the repository in Eclipse? Or from the command line?

      Reply

Leave a Reply