Build your own custom Eclipse

In this tutorial I’ll show how to build a custom Eclipse distribution with Maven/Tycho. We will create an Eclipse distribution including our own features/plugins and standard Eclipse features, trying to keep the size of the final distribution small.

The code of the example can be found at: https://github.com/LorenzoBettini/customeclipse-example

First of all, we want to mimic the Eclipse SDK product and Eclipse SDK feature; have a look at your Eclipse Installation details

eclipse SDK installation details

You see that “Eclipse SDK” is the product (org.eclipse.sdk.ide), and “Eclipse Project SDK” is the feature (org.eclipse.sdk.feature.group).

Moreover, we want to deal with a scenario such that

Our custom feature can be installed in an existing Eclipse installation, thus we can release it independently from our custom Eclipse distribution. Our custom Eclipse distribution must be updatable, e.g., when we release a new version of our custom feature. 

The project representing our parent pom will be

  • customeclipse.example.tycho

The target platform is defined in

  • customeclipse.example.targetplatform

For this example we only need the org.eclipse.sdk feature and the native launcher feature

We created a plugin project and a feature project including such plugin (the plugin is nothing fancy, just an “Hello World Command” created with the Eclipse Plug-in project wizard):

  • customeclipse.example.plugin
  • customeclipse.example.feature

We also create another project for the p2 repository (Tycho packaging type: eclipse-repository) that distributes our plugin and feature (including the category.xml file)

  • customeclipse.example.site

All these projects are then configured with Maven/Tycho pom.xml files.

Then we create another feature that will represent our custom Eclipse distribution

  • customeclipse.example.ide.feature

This feature will then specify the features that will be part of our custom Eclipse distribution, i.e., our own feature (customeclipse.example.feature) and all the features taken from the Eclipse update sites that we want to include in our custom distribution.

Finally, we create another site project (Tycho packaging type: eclipse-repository) which is basically the same as customeclipse.example.site, but it also includes the product definition for our custom Eclipse product:

  • customeclipse.example.ide.site

NOTE: I’m using two different p2 repository projects because I want to be able to release my feature without releasing the product (see the scenario at the beginning of the post). This will also allow us to experiment with different ways of specifying the features for our custom Eclipse distribution.

Product Configuration

This is our product configuration file customeclipse.example.ide.product in the project customeclipse.example.ide.site and its representation in the Product Configuration Editor:

custom eclipse product configuration1

Note that we use org.eclipse.sdk.ide and org.eclipse.ui.ide.workbench for launching product extension identifier and application (we don’t have a custom application ourselves).

ATTENTION: Please pay attention to “uid” and “id” in the .product file, which correspond to “ID” and “Product” in the Product definition editor (quite confusing, isn’t it? 😉

This product configuration includes our customeclipse.example.ide.feature; we also inserted in the end the standard start level configuration, and other properties, like the standard workspace location.

The pom in this project will also activate the product materialization and archiving (we also specify the file name of the zip with our own pattern):

We chose NOT to include org.eclipse.example.ide.site as a module in our parent pom.xml: we include it only when we enable the profile build-ide: installing and provisioning a product takes some time, so you may not want to do that on every build invocation.  In that profile we add the customeclipse.example.ide.site module, this is the relevant part in our parent pom

In this profile, we also specify the environments for which we’ll build our custom Eclipse distribution. When this profile is not active, the target-platform-configuration will use only the current environment.

In the rest of the tutorial we’ll examine different ways of defining customeclipse.example.ide.feature. In my opinion, only the last one is the right one; but that depends on what you want to achieve. However, we’ll see the result and drawbacks of all the solutions.

You may want to try the options we detail in the following by cloning the example from https://github.com/LorenzoBettini/customeclipse-example and by modifying the corresponding files.

Include org.eclipse.sdk

The first solution is to simply include the whole org.eclipse.sdk feature in our customeclipse.example.ide.feature:

You can run the maven build specifying the profile build-ide

To get the materialized products (and the corresponding zipped versions).

NOTE: if you enable the tycho-source-feature-plugin in the parent pom to generate also source features, you’ll get this error during the build:

That’s because it tries to include in customeclipse.example.ide.feature.source the source feature of org.eclipse.sdk, which does not exist (org.eclipse.sdk already includes sources of its included features). You need to tell the tycho plugin to skip the source of org.eclipse.sdk:

The build should succeed.

Let’s copy the installed product directory (choose the one for your OS platform) to another folder; we perform the copy because a subsequent build will wipe out the target directory and we want to do some experiments. Let’s run the product and we see that our custom IDE shows our custom feature menu “Sample Menu” and the corresponding tool bar button:

If we check the installation details we see the layout mimicking the ones of Eclipse SDK (which is included in our product)

custom eclipse sdk installation details

Now let’s run the build again with above maven command.

If you have a look at the target directory you see that besides the products, in custom.eclipse.ide.site/target you also have a p2 repository,

custom ide site target

we will use the p2 repository to try and update the custom ide that we created in the first maven build (the one we copied to a different directory and that we ran in the previous step). So let’s add this built repository (in my case is /home/bettini/work/eclipse/tycho/custom-eclipse/customeclipse.example.ide.site/target/repository/) in the custom ide’s “Install New Software” dialog.

You see our Example Feature, and if you uncheck Group items by category you also see the Custom Eclipse Project SDK feature (corresponding to customeclipse.example.ide.feature) and Custom Eclipse SDK (corresponding to our product definition uid customeclipse.example.ide).

custom ide install new software 1 custom ide install new software 2

But wait… only the product is updatable! Why? (You see that’s the only one with the icon for updatable elements; if you try “Check for updates” that’s the only one that’s updatable)

Why can’t I update my “Example Feature” by itself?

If you try to select “Example Feature” in the “Install” dialog to force the update, and press Next…

custom ide install new software force 1

you’ll get an error, and the proposed solution, i.e., also update the product itself:

custom ide install new software force 2

And if you have a look at the original error…

custom ide install new software force 3

…you get an idea of the problem beneath: since we INCLUDED our “customeclipse.example.feature” in our product’s feature “customeclipse.example.ide.feature” the installed product will have a strict version requirement on “customeclipse.example.feature”: it will want exactly the version the original product was built with; long story short: you can’t update that feature, you can only update the whole product.

Before going on, also note in the target directory you have a zip of the p2 repository that has been created: customeclipse.example.ide.site-1.0.0-SNAPSHOT.zip it’s about 200 MB!  That’s because the created p2 repository contains ALL  the features and bundles INCLUDED in your product (which in our case, it basically means, all features INCLUDED in “customeclipse.example.ide.feature”).

Require org.eclipse.sdk

Let’s try and modify “customeclipse.example.ide.feature” so that it does NOT include the features, but DEPENDS on them (we can also set a version range for required features).

Let’s build the product.

First of all, note that the p2 repository zip in the target folder of customeclipse.example.ide.site is quite small!  Indeed, the repository contains ONLY our features, not all the requirements (in case, you can also force Tycho to include all the requirements), since, as stated above, the required feature will not be part of the repository.

Now let’s do the experiment once again:

  1. copy the built product for your OS into another directory
  2. run the product custom ide
  3. run another maven build
  4. add the new created p2 repository in the custom ide “Install new software” dialog

Well… the Example Feature does not appear as updatable, but this time, if we select it and press Next, we are simply notified that it is already installed, and that it will be updated

custom ide install new software force 4

So we can manually update it, but not automatically (“Check for updates” will still propose to update the whole product).

To make a feature updatable in our product we must make it a “Root level feature” (see also http://codeandme.blogspot.com/2014/06/tycho-11-install-root-level-features.html).

At the time of writing the Eclipse product definition editor does not support this feature, so we must edit the .product definition manually and add the line for specifying that customeclipse.example.feature must be a root level feature:

Let’s build again, note that this time the p2 director invocation explicitly installs customeclipse.example.feature

Let’s do the experiment again; but before trying to update let’s see that the installed software layout is now different: our Example Feature is now a root level feature (it’s also part of our Custom SDK IDE since it’s still required by customeclipse.example.ide.feature but that does not harm, and you may also want to remove that as a requirement in customeclipse.example.ide.feature).

custom eclipse sdk installation details 2

Hey! This time our “Example Feature” is marked as updatable

custom ide install new software 3

and also Check for updates proposes “Example Feature” as updatable independently from our product!

custom ide install new software 4

What happens if we make also customeclipse.example.ide.feature” a root feature? You may want to try that, and the layout of the installed software will list 3 root elements: our product “Custom Eclipse SDK”, our ide.feature “Custom Eclipse Project SDK” (which is meant to require all the software from other providers, like in this example, the org.eclipse.sdk feature itself) and our “Example Feature”.

This means that also “Custom Eclipse Project SDK” can be updated independently; this might be useful if we plan to release a new version of the ide.feature including (well, depending on) other software not included in Eclipse SDK itself (e.g., Mylyn, Xtext, or something else). At the moment, I wouldn’t see this as a priority so I haven’t set customeclipse.example.ide.feature as a root level feature in the product configuration.

Minimal Distribution

The problem of basing our distribution on org.eclipse.sdk is that the final product will include many features and bundles that you might not want in your custom distribution; e.g., CVS features, not to mention all the sources of the platform and PDE and lots of documentation. Of course, if that’s what we want, then OK. But if we want only the Java Development Tools in our custom distribution (besides our features of course)?

We can tweak the requirements in customeclipse.example.ide.feature and keep them minimal (note that the platform feature is really needed):

Build the product now.

Note also that the installed software has been reduced a lot:

custom eclipse minimal 4

The size of the zipped products dropped down to about 90Mb, instead of about 200Mb as they were before when we were using the whole org.eclipse.sdk feature.

However, by running this product you may notice that we lost some branding

  1. There’s no Welcome Page
  2. Eclipse starts with “Resource” Perspective, instead of “Java” Perspective
  3. Help => About (Note only “About” no more “About Eclipse SDK”) shows:

custom eclipse minimal 2

To recover the typical branding of Eclipse SDK, we have to know that such branding is implemented in the bundle org.eclipse.sdk (the bundle, NOT the homonymous feature).

So, all we have to do is to put that bundle in our feature’s dependencies

Rebuild, and try the product: we have all the branding back! 🙂

I hope you find this blog post useful 🙂

The sources of this example can be found here: https://github.com/LorenzoBettini/customeclipse-example

19 thoughts on “Build your own custom Eclipse

  1. Andrey Loskutov

    Thanks Lorenzo, great tutorial! Haven’t tried it but immediately remembered how much pain I had to build my custom Eclipse IDE two years ago (CBI build was at the very beginning).

    Reply
  2. Kaj Kandler

    Thanks Lorenzo,
    great post. I’m struggling with including my required component in my eclipse plugin and installing it in Luna (Juno/Kepler works just fine) – https://www.eclipse.org/forums/index.php/t/1063735/
    I have a few questions to regarding your example.
    * Is there a particular reason that you have the target platform pom file being a “pom” instead of a “eclipse-target-definition”
    * What does the “attach-artifact” actually do, because I can’t detect any difference in my result.

    I also try to understand how the required mechanism works in detail. If I require a component that has been defined in my target platform, where does that URL ref for the P2 repo get stored in the target P2 repo? I have searched, but did not find anything in my target repo that would identify the P2 update site of the required component (nebula in my case).

    Reply
    1. Lorenzo Bettini Post author

      Hi Kaj

      I’m using pom instead of eclipse-target-definition because that way I can simply switch the .target file by passing the classifier property (see the parent pom); in that directory you could also see an ant file to create a .target file that points to a mirror in the local computer, so that I can easily test a build without waiting for the remote p2 sites (that could be the subject of a future blog post); the attach-artifact is maven related somehow I guess (I’m not a maven expert). I took inspiration from here: http://eclipsedriven.blogspot.it/2011/07/configuring-eclipse-tycho-maven-plugin.html

      concerning required features, if I understand your question correctly: no URL will be stored in your p2 update site I’m afraid; you have to tell your users about the URLs of required software… that’s something that has always bugged many users… The workflow would be that your users should first add the URL of the required software in the “Install New Software” location (and press ENTER) so that Eclipse will record that update site, and then they can install your software from your p2 update site (they should select the check box “Contact all update sites…”).

      In Mars, they added the possibility to specify references to required software URLs in your category.xml (have a look at the news of Mars milestones). That way, the URLs will be stored in your p2 update site. Unfortunately, Tycho still does not handle this feature; it works only if you export your features directly from Eclipse. Moreover, I think that this works only if you install software in a Mars Eclipse (but I’m not sure).

      If you need your p2 update site to be selfcontained, you can instruct Tycho to include all dependencies; that’s also the subject of the next blog post.

      Reply
  3. Nikos

    Hello
    I am new in eclipse rcp development and came here with the hope to gain some knowledge on the concepts. I just want to let you know that this is a great tutorial for some one with significant development experience in eclipse and eclipse-rcp development , though does not help much anybody trying to begin on the domain. Everything is a bit ambiguous your steps are not define you even start from the middle of the story to begin with ! Anyway it’s a waste of time for somebody that has not experience on the domain because he can hardly make any sense out of it.

    Reply
  4. Alexis Drogoul

    Hi,

    Thanks a lot for your tutorial. I have a question, though, which you might (or not) be able to answer… I’m in charge of a quite large RCP application (https://github.com/gama-platform/gama) where developers used to use PDE build to produce releases, before we recently moved to Tycho for that. One problem we are facing, however, is that if the features in our product are marked with the property “installMode=”root””, they are not exported by PDE build (i.e. they are not present in the plugins directory of the application, and the application is not functional). And if we remove the property, they are correctly exported again. But of course, we lose in that case the ability to update the features in the resulting release…

    Do you have an idea of why it is the case ? And any idea on how we could enable developers to use either PDE build or Tycho while having plugins correctly exported and features marked as updatable ? (keeping PDE build around is for the moment necessary for quick testing of functionalities in the release — and because it is more convenient for first-time developers to just have to click on a button rather than going through the process of Maven/Tycho builds).

    Thanks in advance for any answer, even negative 🙂

    Cheers
    Alexis

    Reply
    1. Lorenzo Bettini Post author

      Hi Alexis

      I have no experience at all with PDE build, so I really don’t know how to handle that with PDE build. Probably, with PDE build, you need to install the “root” features in the product as dependencies. I guess that could be done with p2.inf. But I’m really not sure about that, I’m afraid.

      Reply
  5. Gionata

    Hello Lorenzo,

    great tutorial! I followed your instructions and everything seems to work, except the very last thing: the branding in about dialog and other.

    I have “lost” the branding in the product like you said. But I can’t include org.eclipse.sdk in my feature: the plugin is not found. Should I install something? Which feature?

    I’m using Eclipse 2018-09 but planning to move to 2021-12.

    Thankyou very much.
    Gionata

    Reply
    1. Lorenzo Bettini Post author

      Hi Gionata, glad you enjoyed the tutorial.
      When you say that the plugin “org.eclipse.sdk” is not found, where do you get this error?
      I mean, during the build or in Eclipse somewhere?
      Are you sure you have everything in the target platform (or in your Eclipse installation in case you don’t use a target platform in your development workspace)?

      Reply
      1. Gionata

        I get the error in the feature dep section of the feature.xml file. And in the maven build:

        [ERROR] Cannot resolve project dependencies:
        [ERROR] Software being installed: com.test.mas.rcp.ide.feature.feature.group 0.0.1.qualifier
        [ERROR] Missing requirement: com.test.mas.rcp.ide.feature.feature.group 0.0.1.qualifier requires ‘org.eclipse.equinox.p2.iu; org.eclipse.sdk 0.0.0’ but it could not be found

        p.s. I’m reading your book on Eclipse build automation, a valuable source of information that I’ve been looking for years… 🙂
        Thankyou!

        Reply
          1. Lorenzo Bettini Post author

            Hi

            I don’t think you can paste XML code in comments, or maybe you have to insert it as code, using the editor (if available). In any case, if you use the target platform of my example there should be no problem (start from that target platform and add your additional dependencies).

            Please let me know.

            P.S. I’m happy you’re enjoying the book as well 🙂

            Reply
            1. Gionata

              This is what I have in the target platform:

              org.eclipse.equinox.sdk.feature.group
              org.eclipse.mylyn_feature.feature.group
              org.eclipse.platform.sdk
              org.eclipse.sdk.ide

              is it correct to have plugins and not feature? I can’ find the org.eclipse.sdk.feature.group that is in your target..

              Anyway, now I can find the plugin org.eclipse.sdk as a depency for my ide feature.
              BUT it’s not working.. no about and no welcome page..

              After many trials I’ve found the reason: I’m using a custom product defined by me while you are using “org.eclipse.sdk.ide” as product in the .product file.
              If I use the same everything work.

              So if I define a custom product there is no branding “inherited” from Eclipse?

              Thnkyou very much for your help.

              Reply
              1. Lorenzo Bettini Post author

                If you use a custom product you’ll have to handle branding (see the example created by the standard Eclipse wizard)

  6. natarol

    This article is very useful, thank you
    But I can’t use Tycho. Can you provide .product build tutorial?

    Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.