Eclipse UI Plugins - eclipse

In a custom Eclipse's product We are asking ourselves:
Should we create one single UI plugin for all the user interface matters or should we broke these matters in several plugins (for example, ui.views - ui.preferences - ui.properties etc ...)
It seems Eclipse's "official" products such as CDT, JDT ... only have one UI plugin and some third party plugins I am using have several ui plugins (Papyrus for example)
I know this is rather a subjective question but I would be interested to learn about the way you manage your UI stuff.
Manu

I'd create separate bundles (or plugins) for each independently usable component. So if I have e.g. a view that can be used without some other things, I'd put it in a bundle of its own. I find that this makes it easier to configure the feature, replace certain parts, provide custom combinations of components, handle dependencies, and such.

If your plugin does one thing (e.g. add a menu item to order pizza) it makes little sense to split it up, you're just introducing complexity. The modularity of your product is the key factor in deciding how to split the functions into plugins. Consider the functionality you're trying to deliver and whether there are any optional components or pieces that may be useful in isolation.
Take m2eclipse as an example, it has multiple UI plugins, but that is because they are functionally separate. The XML editor is certainly a useful UI addition, but users of the core function (dependency management) don't necessarily need it so it makes sense to bundle it separately and make it optional.

Ignoring anything specific to Eclipse, I would say from a product support perspective it makes much more sense to have a single plug-in. This has the following benefits:
Every customer has the same environment, so if someone contacts you with a problem you know what they have.
You have to test a single configuration. If you split your code into 3 plug-ins that's 7 different configurations you have to test.
In future you won't have to worry about which plug-in new functionality should be added to.

Related

Eclipse 4 RCP How to launch another plug in in a new window

I have an e4 RCP which needs all the screen real estate. I have developed a second RCP that is in effect a relatively simple single-function plug-in, with currently only one part. I want the user to be able to launch the second from the first, then terminate it, all on demand.
As I understand it, I have 3 options:
Launch a new workbench for the second, written as a plug-in. I assume this uses more resources and also has the problem that I need to track and distinguish events which will go to both.
Write the second as a model fragment plug-in that extends the first. This has the advantage that I can keep on adding to the second plug-in by declaration in the model editor. However, I believe this requires attaching to an existing container in the main model. I could add a new container to the main model and write code to flip containers in and out but it is all done in the model editor currently, and more importantly the functions carried out by the second plug-in are quite different from those of the first (main) RCP, so I fear the user will find the UI change confusing.
Use EModelService and write code to create a new TrimmedWindow and then child PartStack, and Part, and all the Handlers. I have not yet found enough documentation to fully understand the implications, advantages and disadvantages of this - aside from the obvious ones that the former declarations now have to be programmed and coupling is tighter.
It looks to me like Eclipse itself uses approach 1 for two of its menu items:
Help Contents
Eclipse Marketplace
From the UI perspective, the kind of UI separation of functions that I want to achieve is very much like these two items. Hence I am leaning to option 1.
Any corrections or alternatives?
You could possibly use a PerspectiveStack with two perspectives containing the windows for your two apps. The second app can be in model fragment.
You can then just use EPartService.switchPerspective to switch between them.

Architecture for plugins to be loaded in runtime

Considering that I am developing an end-user software program (as an uberjar) I am wondering what my options are to make it possible for the user to download a plugin and load that during runtime.
The plugin(s) should come compiled and without source code, so sth. like load is not an option.
What existing libraries (or ways of Java...?) exist to build this on?
EDIT: If you are not sure I would also be satisfied with a way that costs a reboot/-start of the main-program. However, what is important is that the source-code won't be included in any JAR file (neither main application nor plugin-jars, see :omit-source of Leiningen documentation).
To add a jar during runtime, use pomegranate which lets you add a .jar file to the classpath. Plugins of your software should be regular Clojure libs that follow certain conventions that you need to establish:
Make them provide (e. g. in an edn) a symbol to an object implementing a constructor/destructor mechanism such as the Lifecycle protocol in Stuart Sierras component library. In runtime, require and resolve that symbol, start the resulting object and hand it over to rest your programs plugin coordination facilities.
Provide a public API in your program that allows the plugins to interact with it in ways that you coordinate asynchronously e. g. with clojure.core.async (don't let one plugin block the entire program).
Make sure that the plugins have a coordinated way to expose their functionality to each other only if they desire so to enable a high degree of modularity among your plugins. Make sure that your plugin loader is capable of detecting dependencies among plugins and is capable of loading and unloading them in the right order.
I've not tried it myself, but you should in theory be able to get OSGi to work with Clojure.
There's a Clojure / OSGi integration library here:
https://github.com/aav/clojure.osgi
If I were to attempt to role my own solution, I would try using tools.namespace to load and unload plugins. I'm not entirely sure it will work, but it's certainly in the right direction. I think one key piece is that the plugin jars will have to be "installed" in a location that's already on the classpath.
Again, this is only the start of one possible solution. I haven't tried doing this.

Setting start levels for dynamic Eclipse features: alternatives to p2.inf?

I have an Eclipse-based OSGi application consisting of bundles organised in features. I use a product definition to launch the application. In this definition, I can also set start-levels for my bundles.
Now imagine I want to add a feature to the running application. Is a p2.inf file the only way to specify start levels for the bundles in this feature? Re-defining and re-starting the product does not sound like an optimal solution as it's not really dynamic.
I am not aware of any real tooling support for setting start levels for bundles on the feature level. The only option you have is manual hacking with a p2.inf.
I think the reason that setting start levels is only really supported for products is that p2 can't handle the case where start levels are specified multiple times. This could easily happen if setting start levels on feature level was encouraged.
So, you can make this work on feature level, but only if you know what you do.
I have the same problem I believe: I have a feature that is both part of a packaged product and present on an update site to be installed into an Eclipse IDE. And I also want to set the start-level for some of the plug-ins to ensure a very early start-up.
I have overcome this with a p2.inf file with the following content:
instructions.configure=setStartLevel(startLevel:1);markStarted(started: true);
instructions.unconfigure=setStartLevel(startLevel:-1);markStarted(started: false);
(I don't think I need to specify the start-level in the product definition anymore though I have not tried to remove this yet.)
I originally used start-level 2, but at least for Juno packages, there are some plug-ins that are started at level 1 so I now use level 1 as well.

Eclipse product: Export multiple versions of a product which has slight variations

This is a relatively open ended question so I wouldn't just mind being pointed in the right direction.
I have a product that uses the Eclipse workbench to allow users to program in a custom language. For this product, I will also have some minor UI and internal changes for a lighter version to be exported. For example, a full version of the product contains some extra views and menus, and behaves slightly differently (like when creating a new file) where as the ligher version does not contain a lot of view and has a couple of different more simplified ones.
I do not want to make a copy of my workspace and then have 2 separate workspaces for a full version and a lighter version as that will be difficult to maintain in the long run especially when there are changes in code relevant to both. I want to be able to export both, full and light versions of a product from a common workspace.
How can I go about this? Or where can I start looking?
The product is a collection of features and uses the Eclipse workbench as its base application.
I would like to clarify that I am asking how I could hide a view for the full or light version, as an example. I know in C#, we have options like #if. I have seen a lot of questions which refer to having 2 different versions of the same code, but nothing about how they could have 2 different versions of the same code.
You want the Eclipse RCP book it really fully explains how to do this. And to do it you need a solid understanding of the concepts of Eclipse plugin, feature, product, fragment and a few other things.
Essentially you can segment your application in to multiple plugins (have a base plugin for example, and then another that provides additional functionality). Then you organize those plugins into features that are the collection of the functionality to be installed. The notion of a "product" in Eclipse has to do with the branding, so you would probably have two products, a lite and a full one. The products could have a branding plugin (where the product is actually declared).
This should get you started.

Large apps in GWT: one module, or several?

In order to provide nice URLs between parts of our app we split everything up into several modules which are compiled independently. For example, there is a "manager" portion and an "editor" portion. The editor launches in a new window. By doing this we can link to the editor directly:
/com.example.EditorApp?id=1
The EditorApp module just gets the value for id and loads up the document.
The problem with this is ALL of the code which is common between the two modules is duplicated in the output. This includes any static content (graphics), stylesheets, etc.
And another problem is the compile time to generate JavaScript is nearly double because we have some complex code shared between both modules which has to be processed twice.
Has anyone dealt with this? I'm considering scrapping the separate modules and merging it all back into one compile target. The only drawback is the URLs between our "apps" become something like:
/com.example.MainApp?mode=editor&id=1
Every window loads the main module, checks the value of the mode parameter, and and calls the the appropriate module init code.
I have built a few very large applications in GWT, and I find it best to split things up into modules, and move the common code into it's own area, like you've done. The reason in our case was simple, we had some parts of our application that were very different to the rest, so it made sense from a compile size point of view. Our application compiled down to 300kb for the main section, and about 25-40kb for other sections. Had we just put them all in one the user would have been left with a 600kb download, which for us was not acceptable.
It also makes more sense from a design and re-usability point of view to seperate things out as much as possible, as we have since re-used a lot of modules that we built on this project.
Compile time is not something you should generally worry about, because you can actually make it faster if you have seperate modules. We use ant to build our project, and we set it to only compile the GWT that has changed, and during development to only build for one browser, typical compile times on our project are 20 seconds, and we have a lot of code. You can see and example of this here.
One other minor thing: I assume you know that you don't have to use the default GWT paths that it generates? So instead of com.MyPackage.Package you could just put it into a folder with a nice name like 'ui' or something. Once compiled GWT doesn't care where you put it, and is not sensitive to path changes, because it all runs from the same directory.
From my experience building GWT apps, there's a few things to consider when deciding on whether you want multiple modules (with or without entry points), or all in one: download time (Javascript bundle size), compile time, navigation/url, and maintainability/re-usability.
...per download time, code splitting pretty much obviates the need to break into different modules for performance reasons.
...per compile time, even big apps are pretty quick to compile, but it might help breaking things up for huge apps.
...per navigation/url, it can be a pain to navigate from one module to another (assuming different EntryPoints), since each module has it's own client-side state...and navigation isn't seamless across modules.
...per maintainability/re-usability, it can be helpful from an organization/structure perspective to split into separate modules (even if there's only one EntryPoint).
I wrote a blog post about using GWT Modules, in case it helps.
Ok. I really get the sense there really is no "right" answer because projects vary so much. It's very much dependent on the nature of the application.
Our main build is composed of a number of in-house modules and 3rd party modules. They are all managed in seperate projects. That makes sense since they are used in different places.
But having more than one module in a single project designed to operate as one complete application seems to have overcomplicated things. The original reason for the two modules was to keep the URL simple when opening different screens in a new window. Even though had multiple build targets they all use a very large common subset of code (including a custom XML/POJO marshalling library).
About size... for us, one module was 280KB and the other was just over 300KB.
I just got finished merging everything back into one single module. The new combined module is around 380KB. So it's actually a bit less to download since most everyone would use both screens.
Also remember there is perfect caching, so that 380KB should only ever downloaded once, unless the app is changed.