Eclipse PDE Open-Source Contribution
Image from the Eclipse IDE Github page.

Eclipse PDE Open-Source Contribution

About the Project


The Eclipse Plug-in Development Environment provides tools to create, develop, test, debug, build, and deploy Eclipse plug-ins, fragments, features, update sites, and RCP products. It’s like a fully equipped workshop for making add-ons and custom desktop programs using the Eclipse platform. You can design your software, test it, fix problems, and package it so others can easily install it.

In order to extend the capabilities of the Eclipse IDE the Eclipse PDE gives open-source contributors and developers a platform to create extensions, plug-ins, and stand-alone Rich Client Platform applications. Rich Client Platforms are desktop applications built using the Eclipse framework. An example of some stand-alone RCP application built using the Eclipse Plug-in Development Environment (Eclipse PDE for short)  are Xmind and KNIME. Xmind is a mind mapping and collaboration desktop application that incorporates artificial intelligence while KNIME is a data analytics and data science tool that lets you build data workflows of any complexity with, no-code, drag-and-drop visual programming. Both of these desktop applications use the Eclipse architecture and plug-in tooling  to create their products and features making Eclipse PDE not just a plug-in development tool for the Eclipse IDE but also an enterprise grade application builder. 

Eclipse is used by contributors who extend the Eclipse IDE through plug-in development and software developers who want to build stand-alone RCP applications. It provides comprehensive OSGi tooling, which makes it an ideal environment for component development, not just Eclipse plug-in development. It’s also helpful for enterprise tool-builders working for large corporations with specific workflows. This is because these enterprises can use Eclipse PDE to create custom tools for their internal needs. 

This is a recording of me going over the Eclipse PDE, exploring the platform in order to get a product sense to start making contributions to the platform. 

The Eclipse IDE is one of the most widely used Java IDE’s worldwide. The tooling as well as IDE architecture is built using modular plugins through Eclipse PDE. Eclipse PDE has a moderately sized but committed user base of plugin and RCP application developers. While it’s hard to get a precise number of Eclipse PDE users it’s estimated to be in the 10,000s of users world-wide. Eclipse PDE is a plug-in development environment for the Eclipse IDE. Making Eclipse PDE an important tool for developers worldwide. 

The Issue


“The Eclipse PDE Manifest editor currently lacks UI support for configuring the jars.extra.classpath attribute. As a result, developers often misuse the additional.bundles attribute to include dependencies intended only for compilation” which causes confusion because additional.bundles adds them as runtime dependencies. Building a feature to alleviate this misuse of additional.bundles is the issue that I’ve tackled throughout this 8 week experience as an open-source contributor. 

Here’s a link to our github issue: https://github.com/eclipse-pde/eclipse.pde/issues/1407 

This issue is important as it started out as a UI problem where developers would confuse jars.extra.classpath with additional.bundles due to poor UI placement and lack of dedicated support in the Manifest editor. To provide some background on this issue I’ll define what bundles and classpath mean first. 

Bundles are the fundamental unit of deployment (similar to a module). It can expose services, consume services, and provide other functionalities. Whereas the classpath is the list of locations (folders, JAR files, plug-ins, etc.) where the JVM and compiler look for classes and resources.

A prior PR addressed part of this by expanding the section where developers add compile only dependencies by default as a way to make it more discoverable. But now maintainers want to extend functionality so that jars.extra.classpath can reference bundles directly from the workspace or target platform. This enhancement will better align with real-world plugin development workflows, making it easier to add compile-only dependencies without manual configuration. Updating the documentation with the new feature will also ensure the community understands these new capabilities, reducing confusion and improving project behavior consistency.

I decided that it was necessary to find the class files that were responsible for the additional.bundles and jar.extra.classpath logic. I used grep to search through the codebase to see if it can filter out the relevant files. These were the files I narrowed down my search to.

Article content
Article content
Add button under the Dependencies tab to add bundles (inspiration logic will be taken from this button logic).
Article content
Add bundles view with available bundles from workspace and target platforms.

Codebase overview


This table is an overview of the tech stack used to make the Eclipse PDE project.

Article content

Before diving into drafting a plan of implementation for this issue, it would be beneficial to understand the system design of Eclipse. Knowing how all these frameworks mentioned above in the table come together to create the Eclipse PDE at a system level will aid our understanding of the issue and the Eclipse PDE platform. Below is my understanding of the system design of the Eclipse PDE.

Article content
System Diagram of Eclipse PDE

Data Flow inside Eclipse PDE


A user walkthrough that ties user actions to how the Eclipse PDE handles those inputs can give us an even better understanding and help us isolate the segments in the codebase that require updating. Here’s an example walkthrough of an Eclipse PDE user doing a common task, adding a compile-time JAR (Java Archive) to a plug-in via “Add JARs...”  and then launching the plug-in in an Eclipse workbench. I’ll use the stand-in name “John” as a java developer using the Eclipse PDE platform in this scenario. 

  1. John opens the plug-in in the Manifest editor by double-clicking META_INF/MANIFEST.MF. PDE then opens its multi-tab form editor.

Article content
PDE Form editor with tabs like Overview, Dependencies, Runtime, Extension Points, Build, etc.

  • Under the hood: a PDEFormEditor hosts pages like Build Page. Each page wires up sections for classpath. For example for the Build page the section that would be wired up is BuildClasspathSection.java.

2. John switches to the Build tab → Extra classpath entries. In this section John sees a table of entries and three buttons (e.g. Add Jars…, Remove). Our friend John proceeds to click Add Jars…

Article content

  • Under the hood: BuildClasspathSection.CreateClient(...) creates the table and buttons. Clicking Add JARs… runs handleNew(...), which opens an ElementTreeSelectionDialog scoped to John’s workspace. Then the dialog is filtered to valid resources, aka JARs only.

Article content
CreateClient(...) function inside BuildClassPathSection class

3. John selects one or more JARs from the workspace. He picks lib/foo-utils.jar in his plug-in (or another workspace project) and presses OK.

Article content

  • Under the hood: For each selected IResource, PDE computes a token
  • If the resource is in the same project: the project-relative path, e.g. lib/foo-utils.jar.
  • If it’s in another plug-in project: a platform URL, e.g. platform:/plugin/com.example.other/lib/bar.jar.
  • BuildClasspathSection.addClasspathToken(...) ensures an IBuildEntry exists for jars.extra.classpath and adds the token(s).

4. The editor then shows John his JARs on the Extra Classpath table. 

Article content

  • Under the hood: The in-memory IBuildModel holds: Entry name and tokens (the path/urls added). The section also listens for model changes and refreshes the table viewer.

5. John saves the editor.

  • Under the hood: The WorkspaceBuildModel serializes IBuildModel and then writes to build.properties. The project then rebuilds automatically. 

Article content
Eclipse PDE adds the token to build.properties as soon as you add it through the UI interface.

6. John chooses to run the application. by pressing Run As → Eclipse Application.

Article content

  • Under the hood: PDE generates a runtime OSGi (Equinox) launch using the selected target platform and workspace plug-ins. The framework resolves bundles using MANIFEST.MF. 

7. Results: John’s plug-in compiles (thanks to the extra JAR on the build classpath). The runtime workbench starts; your plug-in is installed and started according to OSGi resolution. If you set things up correctly for runtime (e.g., via Bundle-Classpath or proper bundle dependencies), the plug-in works as expected. 

Here’s a side project that I made using the Eclipse PDE to show when a plug-in works correctly. It’s a simple Employee Management Perspective with multiple views, tables, and tabs to manage employee data. I haven’t populated it with data so it’s empty for now. I just wanted to create this as a proof of concept to understand the architecture behind Eclipse PDE and the workflow of plug-in creation. Here’s a github link to this project https://github.com/Phinhas214/Employee-Management 

Article content
Plug-in Perspective side project I built using the Eclipse PDE.

Challenges


After me and my team figured out how to add a button and hook all the bundle resources from workspace and target platforms to the button view, I ran into an issue. 

I needed to put a description of where the user can add compile only dependencies to their plug-in in the Dependencies tab. I also wanted to add a hyperlink in the description that would take the user to the Build tab where they can find the new Add Bundles button that I worked on. This plan was working well until I had to add a hyperlink and code the logic for it. 

First I had to edit the text of the existing description inside Automated Management of Dependencies. I found the variable to update to be SecondaryBundlesSection_desc found inside pderesources.properties file. 

I looked at the logic of how other hyperlinks were implemented within the codebase as a starting point. I figured out that in order to add logic to a hyperlink you just need to add this simple linkActivated(...) method inside the createClient(...) function. However, this change would end up crashing the entire tabs view. Every tab starting from the overview tab to build.properties would show an error log and the stack trace. 

Article content

I decided to skim through the stack trace to look at where the bug is. As you can see in the Image above the first line the stack trace was pointing to was irrelevant to what I changed. I updated the DependencyManagementSection.java but the stack trace issue was pointing to a file I didn’t change. So I looked for any relevant files in the stack trace and the first one I found was for DependencyManagementSection.java on line 206 (as seen in the image below). The code logic here was responsible for setting the text and rendering it. I changed one of the parameters of the setText(...) function to be false for parseTags boolean argument to render the text as-is instead of formatting the hyperlinks.

Article content

The result of this was that the platform didn’t crash and text was rendered. However, my hyperlink didn’t show up as a result of my update to not render any of the hyperlink tags. What happened instead was that now the program rendered the raw html along with the description. Even though this isn’t a complete fix, I now have isolated the issue to be about some logic that happens when I try to parse HTML tags.

Article content
Raw HTML tags being rendered along with the description

With this in mind my second approach was to talk to my teammates about this issue that I was facing to hopefully pair program our way out of it as they were also running into the same issue. We tried multiple refactoring approaches thinking the issue lied within the new code we updated inside DependencyManagementSection.java class. We were especially targeting the code responsible for switching to the new tab because we didn’t think that the WorkbenchWindow (the class responsible for loading UI elements) was being initiated before we called this line of code. 

public void linkActivated(HyperlinkEvent e) {
	if ("build".equals(e.getHref())) {
	     // Navigate to Build page
	     getPage().getEditor().setActivePage(BuildPage.PAGE_ID);
	}
}        

I tried multiple refactors including manually initiating WorkbenchWindow and separating the logic for page switching outside of createClient(...) function for more readability. However none of these approaches addressed the core of the issue.

Finally, I scheduled a session with the Consulting Software Engineers at CodeDay to help me get unstuck. I met with Ludo, one of the consultants at CodeDay who guided me towards the right direction to solve this issue. After I told him my understanding of the issue and the steps that I took to solve it, he first asked me to let him look at the stack trace. He then continued to give me a high-level overview of how debuggers work and how to use them. After examining the stack trace we came to an understanding that the issue might not even be with the hyperlink logic I added to the DependencyManagementSection.java class. Instead It might be with something else but in order to figure out what’s happening I had to get more proficient at using debuggers. Learning how to use debuggers was the action step of the meeting and understanding that the issue is not with the new logic added to DependencyManagementSection.java class was the insight I gained. So with this information, I researched how debuggers worked and I communicated with my team mates about the insights of this meeting. 

A few days of debugging after this meeting we were able to pinpoint where the issue was based on the feedback I received from the meeting with Ludo. We were able to figure out that in order for the setText(...) function to parse the HTML hyperlink we needed to add the additional appropriate tags at the beginning and end of the string for it to be recognized as a string containing a hyperlink. This fixed our issue as the hyperlink now shows as a blue highlighted text and upon clicking on the hyperlink it would take the user to the Build tab. Here’s the code to show what change helped fix our issue. 

Before: Description declaration without appropriate HTML tags

SecondaryBundlesSection_desc=Augment the plug-in development classpath with the following dependencies without adding them to the MANIFEST.MF file.</p><p>You can go to the <a href="build">Build Configuration</a> to add compile-only dependencies to the plugin.        

After: Description declaration with appropriate HTML tags

SecondaryBundlesSection_desc=<form><p>Augment the plug-in development classpath with the following dependencies without adding them to the MANIFEST.MF file.</p><p>You can go to the <a href="build">Build Configuration</a> to add compile-only dependencies to the plugin.</p></form>

Solution 


The final solution to this issue came down to making a separate button to add compile only bundles inside Extra Classpath Entries. Extra Classpath Entries can be found in the Build tab and this button placement was appropriate in terms of design since adding compile-only bundles to build.properties is most relevant to the Build tab. This is a step-by-step breakdown of how me and my team were able to solve this issue. 

  1. Added a second toolbar button in the section header. By declaring the variable for the button in the PDEUIMessages file.
  2. Then I wired the new button to its handler function. 

@Override
protected void buttonSelected(int index) {
 switch (index) {
   case 0 -> handleNew();       // Add JARs...
   case 1 -> handleNewBundle(); // Add Bundles←new handler function.
   case 2 -> handleDelete();    // Remove
  }
}        

3. I implemented the bundle-picking behavior. I added handleNewButton() which would open the dialog that lets the user pick the bundles from the target platform and their workspace. It would also ensure that the build model has an entry for jars.extra.classpath. It would then add this bundle as a token in this format platform:/plugin/<bundle.symbolicName>/. 

4. I added imports for PluginSelectionDialog, IPluginModel, IFragmentModel, PDEPreferencesManager, PDELaunchingPlugin, and ILaunchingPreferenceConstants used in the new handler. These imports were added because of the functions needed to create the dialogue view and the Add Bundle… button.

With these implementations now there’s a second header button Add Bundles that appears next to Add JARs. Clicking this button lets you choose bundles and adds tokens into the same jars.extra.classpath build entry, so they show up in the Extra Classpath table. This feature was an addition to the PDE UI Components layer of the Eclipse PDE architecture shown earlier in my system design for the platform. The goal is to improve the development process of Eclipse plug-ins by avoiding confusion of compile-only dependencies with dependencies that would be added to the plug-in configuration file. This implementation uses Java as the main programming language as Java is the foundation of Eclipse PDE itself. I also created and customized UI elements such as buttons, and table viewers using the Standard Widget Toolkit (SWT) and JFace. SWT and JFace are frameworks used by the Eclipse PDE to render its UI components.

Testing my implementation was not a hard task as I didn’t even have to use any Eclipse testing framework. Since I was building a UI component I had to run my application as a runtime Eclipse application after minor changes to see how the UI changed. I also had to make sure that things like the token were correctly being added to the build.properties attribute as well as the Extra Classpath Entries

Here’s a link to the pull request of the full solution if you want to check it out. https://github.com/eclipse-pde/eclipse.pde/pull/1916 



Impressive work, Phinhas Asmelash! I really enjoyed reading your deep dive into Eclipse PDE and how you tackled the jars.extra.classpath vs additional.bundles issue. Making this clearer in the Manifest editor is a concrete improvement that will definitely help plugin developers and enterprise tool builders alike. Your persistence in debugging, documenting the system design, and even building a proof-of-concept project shows exactly the kind of open source spirit that makes Eclipse thrive. Looking forward to seeing more of your contributions in the Eclipse Foundation community, and please don’t hesitate to reach out if you’d like to explore other opportunities to get involved! Credits to our Community mentor Olivier Prouvost as well!

awesome contribution! this is the stuff that actually gets you hired. a lot of companies on OfferPilot care way more about your GitHub than your GPA. we help you find them. free at https://offerpilotai.com/u/w3cmh

To view or add a comment, sign in

Others also viewed

Explore content categories