Your First Application Based On Eclipse FAQ

Download as pdf or txt
Download as pdf or txt
You are on page 1of 24

 

Your first Application based on Eclipse ­FAQ 
 
 
 
Introduction 
What are OSGi, Bundle, Plugins and Features 
RCP Application vs. Tool vs. IDE Plugin? 
What is a target platform? 
How to manage dependencies? 
How to deal with versions in OSGi? 
How to setup an API? 
How to split bundles? 
How to set­up a build? 
Eclipse 3.x vs. Eclipse 4 ­ Which Platform to use? 
Option 0 ­ Eclipse 3.x 
Option 1 ­ 3.x Compatibility Layer (3.x API) on Eclipse 4.x 
Option 2 ­ 3.x Compatibility Layer on Eclipse 4.x with some e4 components 
Option 3 ­ A “pure” or “native” Eclipse 4 Application 
Option 4 ­ A “pure” Eclipse 4 Application integrating some 3.x components 
Conclusion 
Soft migration from 3.x to Eclipse 4 (e4)? 
POJOs in 3.x (without Dependency Injection) 
POJOs in 3.x (with Dependency Injection) 
Conclusion 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  1/24 
 
 

Introduction 
Eclipse  is  a  mature  and  powerful  platform,  more  precisely  a  collection  of  open  source 
technologies  and  frameworks.  When  used  right,  it   can  enormously  speed  up your development 
project  and  significantly  reduce  costs  ­  for  the  initial  implementations  as  well as for the ongoing  
maintenance.  
However,  Eclipse  is  also  known  to  add  new   and  sometimes  complex  concepts  to  the  standard 
Java  world,  which   might  not  be  known  from  the  start.  This  can  lead  to  some  frustration, 
non­optimal architectural decisions and therefore some unnecessary additional effort. 
From  our  experience  in  various  Eclipse­based  projects,  we  observe  a  number  of  frequently 
recurring  questions  and  issues.  In article, we will highlight the most important issues to consider 
and  pitfalls  to  avoid.  This  is  not  a detailed tutorial,  showing step by step instructions.The goal of 
this  article  is  to  give an overview of the frequently asked questions  and create an awareness for 
the  most  common  issues.  We  will  provide  some  blueprint  solutions,  guidelines,  and  initial 
pointers  for  where  to  get  more  information  and  how  to  address  them  in  detail.  If  you  miss  a  
questions  in  this article, please get in contact with us, we might  add new sections based on your 
feedback. 
 

What are OSGi, Bundle, Plugins and Features 
From  the  bottom  to  the  top,  Eclipse  is  based  completely  on   these  concepts,  so  let  us  give  a 
short  introduction  to  them.  OSGi  (Open  Service  Gateway   initiative)  is  a  standard  for  a 
Java­based  module  system  which  fundamentally  changes  the  way  applications  are  developed. 
In  pure  and  traditional  Java   applications,  you  have  one  main  method.  All  classes  you  want  to  
use  are  put  on  the  classpath  and  you  have  access  to  all  of  them.  Of  course,  you  can  extend 
Java  applications  by  adding  Jars   to  its  class  path,  but  the  built­in  support  for  modularity  and 
extensibility  during  runtime  is  pretty  limited.  As  an  example,  you   cannot   restrict  the  access  to 
certain  packages  within  a  jar,  you  cannot  explicitly  define  an  API  and  therefore,  you  cannot 
force  a  decoupling  between  different  components.  OSGi  introduces  the  concept  of  a  bundle,  
which is one  single module of your application. Every bundle defines some packages, which can 
be  accessed  by  other  bundles.   All  “internal”  bundles  are  hidden  for  callers.  Therefore  OSGi 
enables  you  to  decouple  components,  we  will  cover   this  more  in  detail  later.  Every  OSGi 
application  can  consist  of   an  arbitrary  number  of   bundles  and  it  is  even  possible  to  add  new 
bundles  to  an  application  that  has  already  been  deployed  and  therefore  extend  them  by  new 
functionalities. 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  2/24 
 
 

 
While  the  main  goal  of  OSGi   is  modularity,  it  provides   many  more  features.  Most  of  them,  like 
dependency  management  or  package  visibility  are   follow­up  requirements  of  the  modular  way 
and  OSGi  application  are   built.   We  will  cover  more  detailed  questions  about  OSGi  later. 
Technically,  an  OSGi   bundle   is  either  a  Jar  file  or  an  unpacked  Jar  file  (directory).  The  only 
difference  to  a  plain  Jar  is  the  existence  of  a  file  called  “MANIFEST.MF”  located  in  a  folder 
“META­INF”.  It  contains  all  additional  meta­information  about  a  bundle,  which   is  processed  by 
the  OSGi runtime. This is mainly: an ID, a version, the dependencies (including a minimum Java 
version),  and  packages  a   bundle  is  providing  to  other  bundles  as API (we will explain this more 
in  detail  later).  The  following  screenshot  shows  the  textual  content  of  a  MANIFEST.MF  file,  if 
you open it in your Eclipse IDE, you will need a form­based editor support to configure it. 
 

 
 
The  Eclipse  IDE  itself  is  an  OSGi  application, that is why it is possible to install new plugins into 
it. This directly leads to the next common question: 
 
What is the difference between a bundle and a plugin? 
or (sorry for the SEO! :­) 
What is the difference between a plugin and a bundle? 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  3/24 
 
 

 
This  questions  leads  back  in the ancient times of Eclipse. The first two major release streams  of 
Eclipse  (1.x  and  2.x)  were  not  based  on  OSGi.  Instead,  Eclipse  implemented  its  own  and 
custom  module  system,  which  allowed  you  to  add  “plugins”  to  an  existing  application.  This  
changed  when  Eclipse   switched   to  OSGi  with  version  3.0  in  2005.  The  original  plugin  concept 
was  discarded,  the  only  concept  that  remained  were  extension  points.   However,  the  term 
“plugin”  was  not  really  gone,  as  it  was  used  commonly.   Therefore,  “plugin”  and  “bundle”  today 
actually  means  the  same  thing.  There  is  one  differentiation,  which  is  often  used:  A  plugin   is 
something,  which  extends  the  Eclipse  IDE,  while  a  bundle  is  part  of  a  general  purpose 
application.  However,  you  cannot  really  rely  on  all  people  are  using   the  definition  this  way.  By 
the  way,  the  switch  from  the  custom   plugin  architecture  to  OSGi  is  the  reason  why  today there 
are  two  artefacts  in  typical  Eclipse  “plugins”,  the  “MANIFEST.MF”  as  defined  by  OSGi  and  the 
“plugin.xml”, which was the former artifact to define all plugin information such as dependencies. 
Today,  the  “plugin.xml”  only  contains  extension  points,  all  other  information  has   moved  to  the 
“MANIFEST.MF”.  The  tooling  of  Eclipse,  which  support  the  development  with  OSGi artefacts is 
also  still  called  “Plugin  Development  Environment”  (PDE).  PDE  mainly  uses  the  term  plugin 
instead  of  bundle,  so  if you want to create a new bundle in the Eclipse IDE,  you select “New” => 
“Plugin project”. 
To conclude the first section, there is one additional artefact missing, a “feature”. 
Features  are  a  way  to  organize  bundles  by  grouping   them.  In  a  typical  Eclipse application,  you 
deal  with  up  to  1000 bundles, it would be hard to manage on that  level of granularity. Therefore, 
bundles  are   grouped into features which provide a consistent set of functionalities. Features can 
be  further  grouped  again  into  other  features.  As  an  example  there  are top­level features for the 
different  IDE  packages  you  can  download  at  Eclipse.  They  contain   then  other  features such as 
“Git Support” or “Java Development Tools”. 

RCP Application vs. Tool vs. IDE Plugin? 
One  of  the  major  source  for  confusion  in  the  Eclipse  world  are  the various use cases. In turn, it  
is  also  one  of  the   key  strengths,  but  it  is  important  to  have  an  initial overview. Like the collision 
between  the  terms  “plugin”  and  “bundle”,  this  confusion  originates  again  in  the  history   of 
Eclipse.  Originally,  Eclipse  was  built  as  a  tool  platform,  as  a  framework  to  build  various 
development  tools  upon.  The  first,  most  famous  and  probably  most  powerful  tool  was  the 
Eclipse  Java  IDE,  also  called  Java  Development  Tools  (JDT).  From the beginning, Eclipse was 
an extensible platform, in fact JDT is just an extension to the pure tool platform. JDT can also be 
extended by additional features that are called a plugins for the IDE. 
Other  tools besides JDT were built on the Eclipse tool platform, as well, e.g. the “C development 
tools”  (CDT).  Many companies  adopted the platform for their own custom  tools. Sometimes they 
reuse  some   features  from  other  tools,  such  as  JDT,  sometimes  they  just  reuse  general   tool 
platform features such as version control integration (e.g. Git). 
However,  over  the  years,  people  started   to  build  application  based  on  Eclipse,  which  had 
nothing  to  do  with  tools  anymore,  but  instead  were  general  purpose  applications.  In  the 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  4/24 
 
 

beginning  this  was  hard  to  do,  because  you  needed  to   “hide”  all  the  tool  related  stuff.  With 
version  3.0,  Eclipse  did  a  reorganization   and  refactoring  to split  framework parts, which are tool 
related  from  parts,  which  could  be  used  in  any  kind  of   application.  The  second  part  was  called 
“Rich  Client  Platform”.  Therefore,  another  use  case  for  using  the  Eclipse  platform  was  officially 
supported,  that  is  to   build  so  called  Rich  Client  Platform  Applications.  These  applications 
depend  on  the  RCP   feature,  not  the  tool  platform.  Finally,  with  version  3.0,  Eclipse  also 
switched  to  OSGi  and   implemented  a  runtime for the standard. So, as  a last possibility, you can 
also  build  a  pure  OSGi  application  without  using  RCP.  This  is  typically  done  for  server 
applications  or  in  the  embedded  area. The following diagram shows an overview of the different 
use case for Eclipse as well as a dependency graph of the available components. 
 

What is a target platform? 
Every  Eclipse  Application  project,  no  matter  if  it  is   an  IDE  plugin,  a  tool,  or  an  RCP  application 
uses  a  target  platform.  However,  many  projects  never  care  about  it,  although  it  is  an  essential 
part  of  the  development  environment.  If  we  look  at  an  Eclipse­based  application  project,  you 
typically  use  the  Eclipse  IDE  to  develop  a   number  of  custom  bundles.  These  are  located  as 
sources  in  your  workspace  (see  following  diagram).  The  bundles  have  typically  some 
dependencies  to  other  bundles,  which  you  have not developed yourself, e.g. Eclipse framework 
components.  To  compile   your  custom  bundles,  those   additional  bundles  are  required.  That  is 
why  these  bundles  are  called  “target  bundles”.  Furthermore,  when  you  start  or  deploy  your 
 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  5/24 
 
 

application,  those  bundles  have  to  be  deployed  as  well.  So  there  needs  to  be  a  location  to 
retrieve  those  “target  bundles”  from. This location is called “Target Platform” as is  defined with a 
“Target Definition”. 

 
A target definition is  basically a collection of locations, where bundles can be retrieved from (see 
the  following  diagram).  All  those  locations  sum  up  to  the  target  platform.  The  simplest  type  of 
location   is  a  plain  directory  containing  the  target  bundles. However, a  target definition is usually 
shared  among  several  developers,  so  a  directory  might  not  be  the  optimal  choice.  The  second 
type  of  location  is  an  update  site,  that  is,  a  location  reachable  over  HTTP  containing  the 
bundles.  The  update  site  can  be  hosted  internally,  or  the  official  update sites at eclipse.org can 
be  used.  Finally,  the  third  type  of  location  is  an  Eclipse  installation.  This  type  is  very  similar  to 
the  directory  type,  it  points  to  the installation directory of an existing Eclipse IDE installation and 
retrieves  the  bundles  from  it.  As  the  Eclipse  IDE  contains  a   lot  of  the  commonly  used  Eclipse 
frameworks,  this  is  a  good  starting  point,  especially  if   you  develop   a  plugin  for  the  IDE. 
However,  as  for  directories,  this  option  is  not  optimal  for  sharing  with  other  developers  as  they 
need to download or access the Eclipse instance you use as a target. 
So,  you  might  wonder,  why  you  never  had  to  think  about  target  platforms  before  and  why  you 
can  compile,  start and deploy your bundles without even defining one. The  reason is the Eclipse 
IDE  ships  with  a  default  target  platform.  This  is  of  type  “Eclipse  Installation”  and  points  to  the 
running  IDE  itself.   That  is  the IDE you use  for development  as all Eclipse IDEs contain the most 
common  Eclipse  frameworks.  Therefore  this  default  does  not  require  any  downloads  or  initial  
setup  to  get  started  with  Eclipse  development.  However,  the  default  does  have  shortcomings. 
First,  you  always  have  to  use  the  exact  same  version  of  IDE  as  target.  If  you  develop  an 
application  based  on  Eclipse,  you  might  not  always  immediately  want  to  update  to  the  latest 
version  of  the platform. If you use your IDE as a target, you are stuck with an older version for it. 
Another  reason  is  that  you  have  to  ensure,  all  developers  have  exactly  the  same  IDE  installed 
including  all   additional  plugins.  Otherwise,  builds  from  within  the  IDE  are  not  reproducible. 
Finally,  if  you  want  to  setup  a  build   server, you would alos need to synchronize it with your IDE. 
So  the  recommendation  is  not  to  use  the  running   IDE  as a target platform, but define the target 
explicitly.  Such  a  configuration  can  be  done  with   a  target  definition  file.  This  enables  you  to  
 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  6/24 
 
 

manage  your  IDE  independently  from  the target of your application. So, you can always use the 


latest version for the IDE, which usually contains improvements for the development. If you want 
to  improve  the  way  you  setup  your  IDE  and  synchronize  its   configuration  with   the  whole  team, 
you should have a look at ​ Oomph​ . 
 

 
 

How to manage dependencies? 
As  we  described  before,  OSGi  enables  you  to  split  an  application  into  an  arbitrary  number  of 
bundles.  Those  can  then  be  combined  into  an  application.  This  provides  a lot of flexibility  when 
creating  your  own   application  based  on bundle that you develop yourself and on bundles, which 
you  reuse  from  other  projects  including  open source components. However, when modularizing 
an  application,  there  are  requirements  for  expressing   and  managing  dependencies  between 
bundles.  Let  us  assume  a  simple  example,   where  you  start  your  project  with  a  monolithic 
component   (bundle  1)  implementing  some  functionality.  Now  you  want  to  add  another  feature. 
To  create  a  modular  application,  you  decide  to  implement  the new feature in a separate bundle 
(bundle  2).  However,  in  the  first  bundle,  you  already  implemented  some  common  functionality, 
which  you  now  want  to  reuse  in  the  second  bundle.  As you do not need everything in bundle 1, 
you  decide  to  move  only  the  common  bit  of  code  into  a  “common  bundle”.  Now,  bundle  1  and 
bundle  2  use this common bundle and therefore they have a dependency on it. This means, you  
cannot deploy bundle 1 and 2 without the common bundle. 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  7/24 
 
 

 
During  runtime,  OSGi  will  resolve   and  bind  the  dependencies  for  you.  However,  you  need  to  
express  dependencies  in  a  formal  way  to  enable  this.  There  are   two  different  ways  of 
expressing  dependencies  in  OSGi,  both  are  managed  in  the  MANIFEST.MF  file  of  an  OSGi 
bundle.  If  you  open  a  MANIFEST.MF  file  in  your  Eclipse  IDE,  you  can  configure  both  types  of 
dependencies on the tab “Dependencies”. More details about the editor can be found ​ here​

● Bundle­based:   This  type  of  dependency  is  managed  in the left list “Required bundles”. If 
you  add  a  bundle  to  this  list,  you  express  that  your  bundle  has  a  dependency  on  the  
other bundle including all its packages. 
● Package­based:  This  type  of   dependency  is  managed  in   the  right  list  “Imported 
packages”.  If  you  add  a  Java  package  to  this  list,  you  express  that  your  bundle  has  a 
dependency  on  this  package,  only.  Therefore,  “package  imports”  are  more  fine­grained 
than   “required  bundles”.  You   also  do  not  need  to  specify,  which  bundle  will  provide   the 
package. Import packages are therefore robust against a package being moved between 
bundles. 
There  are  different  opinions,  which  of  the  two  type  of  dependencies  is  better,  we  will  not  open 
this  discussion  here.  In  a  nutshell,  “import  packages”  are  more  flexible,  more  loosely  coupled,  
and  more  fine­grained,  but  also  more effort, as you  need to be more specific. Therefore, “import 
packages” should be preferred. 

How to deal with versions in OSGi? 
When  talking about dependencies, there comes another important topic, that  is the versions of a 
bundle.  Imagine  a  bundle  1   having  a  dependency  to bundle 2, so it uses some API.  Now, when 
bundle  2  evolves,  it  might  break  its  API,  so  bundle  1  would  no  longer  be  compatible.  To  deal 
with this problem, OSGi enables two things: 
1. Every bundle has a version, which provides information about the compatibility of its API 
2. Dependencies to bundles can be specified with a version range 
An  OSGi  version  number  consists  of  4  parts  separated  by  a  dot:  E.g.  1.1.2.20151102.  More 
details  about  their   meaning  can  be  found  ​ here​.  In  a  nutshell:  A   major  version  jump,  e.g.  from 
1.2.0  to  2.0.0  means,  that  the  API  has   been  changed  in  an  incompatible  way,   all  minor  or 
service  releases  guarantee  backwards  compatibility.  Minor  release,  e.g.  from 1.1.0 to 1.2.0 add 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  8/24 
 
 

new  functionality, so the API can be extended. If you specify  a dependency  to a bundle, you can 


set   a  minimum  required  version  and  a  maximum  (which  is  typically  excluded).  The  minimum 
version  should  be  the  version  with  which  you   start  to  use  a  bundle.  As  an   example,  if you start 
to  use  bundle  2  from  bundle  1,  and  bundle  2  has  a  current  version  1.1.0,  this  should  be  your 
lower  bound  (inclusive).  You  cannot  be  sure  that  your  bundle 1 is compatible with version 1.0.0 
of  bundle 2, as you might use API, which has been added in the 1.1.0 release. The upper bound 
should  be  2.0.0  (exclusive)  as  this  is  the  next  major  release,  which  does  not  guarantee  
compatibility  anymore.  Version  ranges  can  be  set  in  the   MANIFEST.MF  editor,  right  click  a 
dependency and select “properties”. 

How to setup an API? 
Many  of  the  questions  in  this  article  so  far  were  related  to  OSGi,  bundles  and  the  supported 
modularity.  There  is   one  missing  piece,  which  is  a  key  concept  for  achieving  true  modularity, 
that  is  defining  APIs.  OSGi  enables  you  to  split  code  among  bundles,  define  dependencies 
between  them,  and   deploy  them  independently.  However,   without  APIs,  this  will  not   provide 
much  benefit.  The  following  diagram  shows  a  simple  example  of  two  bundles,  where  bundle  1 
accesses  classes  in  bundle  2.  In  fact,   bundle   1  accesses  all  classes  of   bundle   2.  If  you   now 
think  about  some  benefits,  you  want  to  achieve  with modularity, they are not really supported in 
this  case.  As  an  example,  replacing  bundle  2  would  require  you  to  implement  all  classes. 
Additionally, there is no capsulation, every change in bundle 2 can potentially affect bundle 1. 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  9/24 
 
 

 
You  will  achieve  true  modularity  and  benefit  from  it,  if  you  decouple  bundles  as  much  as 
possible,  which is done  by defining APIs. OSGi explicitly supports this. In the MANIFEST.MF file 
of  every  bundle,  you  must   explicitly  specify   which  packages  of  a  bundle  can  be  accessed  by 
other  bundles  (exported  packages)  and  which  cannot.  See  ​ here  ​
for  more  details.  Exported 
packages  define  the  API  of  a  bundle.  Therefor,  the  default  should  be  to  wait  to  import  any 
package  until  you  need   to  define  an  API  for  other  bundles.   API  packages  contain  the   Java 
interfaces   and  classes  the  API  of  a  bundle consists of. Typically, you should prefer interfaces in 
APIs,  this  avoids  dependencies  to  concrete  implementations.  As  shown  in  the  following 
diagram,  other  bundles  only  access  the  API  and  not  any  internal  classes.  The  internal 
implementations  can  be  evolved  and  even  replaced.  As  long  as  the  API  stays  compatible,  you 
do  not  have  to  adapt  bundles,  which  use  it.  Defining  APIs  allows  you  to  decouple  bundles  and 
therefore is the key to benefit from modularity.  
 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  10/24 
 
 

 
There  are  two  additional  conventions  about  package  visibility  in  the  Eclipse  ecosystem.  First,  
internal  packages,  meaning  all  packages   which  are  not   API,  typically  contain  the  key  word 
“internal”.  The  second  convention  is  to  export  internal  packages,  by “hiding” them. If you  do not 
add  a  package  to  the  list   of  exported  packages,  it  is   not  accessible  for  other  bundles. 
Frameworks,  which  are  used  by  anonymous  users, typically want to technically allow accessing 
of  internal  classes.  They  should  still  communicate  that  a  certain  package  is  not  meant  to  be  
accessed,  because  it  is  API.  This  can  be  done  by marking packages with “x­internal”. The PDE 
MANIFEST.MF  editor  supports  this  with  an  additional  option  on package exports. The following 
screenshot  shows  two  packages,  the  first  one  is  API,  the  second  one  is  internal. To hide it, the 
option  “hidden  from  all  plugins  except”  should  be  selected  on  the  right  site.  Hidden  packages 
can  be  technically  accessed,  but  any  callers  will  get  a  “discouraged  access”  warning.  Thereby, 
developers know, that they are using internals, which they should avoid. 

How to split bundles? 
We  have  described  before,  that  OSGi  enables  modularity  for  Java  applications.  It  enables  you 
to  split  a  system  into  bundles  (i.e.  modules),  which  can  be  deployed  independently  from  each 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  11/24 
 
 

other.  If  you  start  to  develop  your  own  bundles,  you  will  need  to  decide  pretty  soon,  how   you 
split  your  code  and  the  features  you  develop  among  bundles.  OSGI  and  the  bundle  concept 
provide  the  technical  foundation  for  modularity,   but  choosing  the  right  level  of  modularity  is  an 
architectural  decision.  We  need to lower  your expectations for this section, creating a good level 
of  modularity  is  not  a  generic  issue  that  can  be  answered  in  a  few   sentence.  Instead,  it   it  very 
much  depending  on  your  system,  project,  and  domain.  However,  there  are  some  generic 
patterns  and  best  practises,  which  we  want  to  describe  in  the  following  section.  Some  of  them 
are  pretty  obvious,  but  it  helps  to  keep  them  in  mind  when  thinking  about  the   bundle   structure. 
Also it helps to keep the typical goals for modularity in mind, which are in a nutshell:  
● Bundle  can  be  developed,  evolved  and  tested  independently,   which reduces complexity 
and improves the maintainability. 
● Bundles  can  be  replaced  independently  if  the  system  is  evolving.  As  an  example,  if  the  
UI of an application is redeveloped, only UI related bundles have to replaced 
● Bundle can be shared and reused (internally or from open source projects) 
● Bundles can extend existing applications (plugin mechanism) 
● Different  sets  of  bundle   can  be  combined  for  creating  different  variations  of  an 
application 
Based  on  those  goals,  we  suggest  the  following  list  of  pattern  and  best practises to modularize 
your code among bundles: 
● Feature­based​ :  A  typical  complex  application  consists  of  several  different  sets  of 
functions.  As  you might want to develop, reuse and deploy them independently, it makes 
sense to develop different features in separate bundles. 
● Split  UI  and  core​ :  Many  features  consist  of  a  core  part,  providing  some  head­less 
business  logic  and  some  UI  components  which  allow  the  user   to  trigger  something  and 
see  the  result.  It  pays  off  to   split  both  parts  of  a  feature  and  especially   keep  the  non­ui 
related  parts  separate.  As  an  example  the  business   logic  can  then  be  reused,  even  if a 
new UI is developed or if the functionality should be available on a server without any UI. 
● Dependency­based​ : This is the more generic pattern for splitting UI and core bundles. It 
means  that  you  look  at  the   dependencies  you  need  to  implement  certain  functionalities 
within  your  bundles.  If   a  bundle  contains  two  features,  which  require  very  different 
additional  technologies  to  realize  the  features,  you  may  consider a split. Splitting UI and 
core   components  is  one  subtype  of  this  pattern.  However,  there  are  many  other 
occurrences,  too.  As  an  example,  if   one  class  in  your  bundle  works  with  files,  while  the 
other  works  with  databases,  you could split the bundle into a file and  into one db bundle. 
If  you  later  on  switch  to   another  database   or  you  want  to  deploy  a  version  of  your 
application without database support, those use cases are much better supported. 
● Keep  entities  separate:  ​ The  entities  of  an   application  (objects  holding  the  data)  are 
typically  accessed  by   most  other  bundles  and  play  a   central   role.  They  are  also  often 
reused  and  evolved  over  a  long  time.  Therefore  it pays of to keep entities separate from 
any business logic or UI concerns and follow a classic MVC pattern. 
● Use  Cases  for  exchanging/extending  things  or  optional  features?  ​ Sometimes,  you 
already  know some concrete requirements you need to fulfil, e.g. you  know that a certain 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  12/24 
 
 

functionality should be extensible or optional. In  this cases, it is typically pretty obvious to 
split bundles in a way to support the required use cases. 
● Use  Cases  for  reusing   things?  ​ You   should  review  things  you  implement to see if they 
could  potentially  be  reused  by  other  products  or  projects  in  the  future.  If  this  can   be 
foreseen, the features which could be reused should be placed in separate bundles. 
As  you  may  have  noticed,   all  the  described  patterns  are  pretty  generic.  At  the  end  it  requires 
some  experience   to  get  to  the  right  level  of  modularity.  However,  if   you  define  good  APIs  and 
thereby  decouple  components,  it  is  possible  to  move  things  around  without  to much adaptation 
effort.  Another  useful  thing  to  do  is  to  define  features,  which  group  your  bundles.  This  enables 
you to keep everything organized, even if the number of bundles grow in your project. 

How to set­up a build? 
There  are  different  build  technologies  to  setup  a  build  for  an  Eclipse   application.  We 
recommend  Maven  Tycho,  it  is  also the  standard build  technology defined  in the Common Build 
Infrastructure (CBI). Tycho is a plugin for maven, which enables two things:  
1. Building Eclipse­specific artefacts, such as bundles or features  
2. It uses the informations stored in MANIFEST.MF files, e.g. the dependencies.  
 
This  is  an  important  detail,  Maven  has  its  own  way  of  specifying  dependencies  (in  pom.xml). 
Tycho enables a “Manifest first” approach, so you do not need to duplicate the information  of the 
Manifest file in the pom.xml. 
There  are  many  tutorials  out  there  on  the  topic  of  setting  up  a  build  with  Maven  Tycho,  in  this 
article,  we  just  want  to  highlight  the  basic  scheme.  In  general,  you  will  need  to  configure  a 
pom.xml  for  every  artefact,  which  is  part  of  the  build.  These  are  typically  three  different  types: 
bundles,  features,  and  products.  The  first  two have already been introduced. The third, product, 
is  an  artefact  to  configure  a  complete  application.  It  is  basically  a  collection  of  bundles  or 
features,  so   it  defines,  what  is  in  your  final   application.  Products  can  be  setup  with  bundles  or 
features,  we  recommend  the   second  option.  The  definition  of  a  product  is   contained  in   a  file 
called  “Product  Definition”,  which  can  be  created  within  your  Eclipse  IDE.  Beside  the  list  of 
bundles  or  features,  a   product  also  contains  information  about  the  branding   of  the  final 
application such as a logo, the splash screen, etc. 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  13/24 
 
 

Eclipse 3.x vs. Eclipse 4 ­ Which Platform to use? 
This is question every Eclipse based project has to deal with. In 2011, an new major release of 
the Eclipse platform was done (Eclipse 4.x). It provides a new API for the workbench, which 
replaces the 3.x API. For a detailed description of the new platform, please have a look at ​ this 
tutorial​

The Eclipse 4 Application Platform provides great support for developing applications and in 
general Eclipse 4 does many things better than Eclipse 3.x. However, that does not mean that 
Eclipse 3.x, more precisely its API is decrepit. There are tons of existing plugins out there based 
on this API and they are still actively developed. The implementation of Eclipse 4 does not 
mean, that the 3.x API is no longer useful. This is especially true in the tools area, many of 
them, e.g. the java development tools, are and will probably stay on the 3.x API for a long time. 
Therefore, before you start an application, you will have to deal with the question of which API it 
is based. In the following sections, I will describe the most important options in detail. 

Option 0 - Eclipse 3.x


This would mean you use an old version of the Eclipse platform (highest one is 3.8). Those 
versions do not contain any components from Eclipse 4. This option is only valid for existing 
tools, which are not actively developed anymore. There are no updates nor service releases for 
the 3.x stream anymore. Sooner or later, you will need to update to option 1, e.g. if the 
contained SWT version no longer supports your windowing system or if you need other fixes. 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  14/24 
 
 

The only alternative is to get ​
Long Term Support​  for your Eclipse 3.x version. New projects 
should not use 3.x. We will not describe this option in more detail. 

Option 1 - 3.x Compatibility Layer (3.x API) on Eclipse 4.x


This is the option used by most tools and applications which existed before Eclipse 4. The 
compatibility layer enables 3.x applications to run on the new Eclipse 4 platform without any 
code adaptation. Most existing projects use this option as a first step towards Eclipse 4. Besides 
the easy migration, you can still use all existing components and frameworks, even if they are 
not migrated to e4. Finally, your application stays backwards compatible, meaning it can still be 
run on 3.x 
To ease migration, the compatibility layer provides the 3.x workbench API and translates all 
calls into the programming model of e4. In the background, it transparently creates an 
Application Model. For example, if the 3.x application registers a 3.x view using an extension 
point, the compatibility layer will create a Part for this view. One important criteria for existing 
applications to work well on the compatibility layer is that they should not use any internal 
workbench API. Aside from this, there should be no source code changes required. However, 
you will probably need to adapt the product or run a configuration of the application. Eclipse 4 
needs additional plugins to work, and as there are no direct dependencies, this will not be 
automatically discovered. These are the plugins you will need to add: 
org.eclipse.equinox.ds : The OSGi plugin enabling declarative services 
org.eclipse.equinox.event: The OSGi event broker 
org.eclipse.equinox.util: Required by the first two 
org.eclipse.e4.ui.workbench.addons.swt: Enables features such as minimizing and maximizing 
parts. 
We have mentioned before, that “there should be no source code changes required”. However, 
whether this is true, depends on the project and more precisely on the usage of the workbench 
API. In general, if you only rely on official API, your code should compile well and the basic 
functionality should generally work. However, there are things in Eclipse 4 which behave a little 
different than in Eclipse 3.x. The reason is obviously the reimplementation of all internals. These 
differences could be slight changes in the look and feel or the behavior, which implicitly worked 
on 3.x, but is not really guaranteed in the API. The only way to find out about those issues is to 
try to test an existing application based on the compatibility layer. Sometimes it is required to fix 
some remaining minor issues on the Eclipse 4 platform to fully support your application. It is 
impossible to estimate the required effort for migrating an existing application on the 
compatibility layer, without evaluating it. Some applications run without any adaptations, for 
others you need a few days or even weeks of work. For supporting your migration project, we 
offer ​
developer support and sponsored development as professional services​ . 
An obvious disadvantage of using the compatibility layer is that you won’t benefit from the new 
concepts, such as the application model, dependency injection and annotations provided by e4. 
Although, some other improvements will still work, such as CSS styling. 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  15/24 
 
 

Option 2 - 3.x Compatibility Layer on Eclipse 4.x with some e4 components


There can be good reasons to keep an application on the compatibility layer, meaning the 3.x 
API. This is especially true for existing applications, as it requires almost no migration effort. 
Additionally, the Eclipse IDE itself is still based on the 3.x API, so if you extend it, you 
automatically need to use the compatibility layer. 
However, it would still be useful to use some of the benefits of the Eclipse 4 programming 
model, especially for newly developed components. Additionally, it would be nice, if components 
could be developed in a way such that they can be used in a 3.x as well as in a pure Eclipse 4 
application. 
There are ways to integrate Eclipse 4 components into an 3.x application based on Eclipse 4.x. 
That enables you to use the Eclipse 4 benefits for newly developed components and still reuse 
all existing plugins. More details are described in the section “Soft Migration to Eclipse 4.x” 
This approach allows you to develop new parts of the application using the benefits of the 
Eclipse 4 programming model and as well as reuse all existing components. Further, the views 
developed in this way can be integrated into any pure e4 application without any adaptations. 

Option 3 - A “pure” or “native” Eclipse 4 Application


The third option, primarily interesting for new projects, is to build a pure Eclipse 4 (e4) 
application without any compatibility layer. Any existing parts of an application should be 
completely migrated to e4. The major disadvantage of this option is that many existing 
components and frameworks cannot be reused. This affects components doing UI contributions 
such as Views. Examples would be the Error Log, the Console View, or existing editors. To use 
them in an e4 application they would have to be migrated to e4 as well. However, components 
without any workbench contributions should work in a pure e4 application. The advantage of this 
approach is obviously that you will have very clean design and you benefit from all the concepts 
in Eclipse 4, such as the Application Model, dependency injection, and the e4 services. 

Option 4 - A “pure” Eclipse 4 Application integrating some 3.x components


In this option you would develop a pure Eclipse 4 application and reuse some 3.x components. 
Components without workbench dependencies can typically easily be integrated into a pure e4 
application. Components with workbench dependencies have to be adapted. Depending on the 
component, this adaptation is often not much effort. Even UI components can often be easily 
reused or adapted to work with e4. However, this needs to be evaluated individually for each 
component. The good news is that if you rely on open source components, everybody is able to 
adapt those. To help you with evaluating and adopting existing components to Eclipse 4, we 
offer ​
developer support and sponsored development as a professional services​ . 

Conclusion
In the end, when and how to migrate to e4 is still one of those “it depends…” decisions. 
Probably the most important criteria is the number of existing components and the number of 
reused third­party components. If you use many existing components you require the 3.x API, 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  16/24 
 
 

and you should probably go for option 1 or 2. If you do not use a lot of 3.x based components, 
or if all of those components can easily be migrated, you should go for option 3 or 4. 
If you have additional options for migrating or mixing the two technologies, let me know and I 
will gladly add it to this post. 

Soft migration from 3.x to Eclipse 4 (e4)? 
This questions is mainly relevant for existing projects or for projects, which have to use the 
compatibility layer. The question is how to do a soft migration to the ​ Eclipse 4 (e4) programming 
model​ . The basic goal is to enable development using the new concepts such as Dependency 
Injection, and Annotations, but without first requiring a complete application migration. So the 
application is still based on the compatibility layer, but it includes some components following 
the Eclipse 4 programming model. As the compatibility layer is used, all existing plugins as well 
as frameworks which require the 3.x API can still be used as before. However, developing new 
UI components for an application following the e4 programming model has two major 
advantages: 
1. The new components are POJOs and therefore very flexible, testable, and reusable. 
2. If the application is migrated to the Eclipse 4 Application Platform, these components are 
ready to be used in e4. 
Interestingly, the first point is worth taking advantage of, even if you are sure that Eclipse 4 will 
not be an option in the near future. The idea is actually pretty simple and isn’t really new at all. 
There are basically two options for how to follow these concepts: with or without dependency 
injection. To explain the basic idea, we will first introduce the manual approach, without 
dependency injection and, in the subsequent section, introduce the Eclipse 4 like approach with 
dependency injection. 

POJOs in 3.x (without Dependency Injection)


The basic concept is to make a clear separation between the code which you develop for a 
custom application and the code that binds your component into the Eclipse workbench. The 
second component depends on the workbench API and is therefore specific to a certain Eclipse 
version, i.e. 3.x or 4.x. The first group of code does not need to be specific to an Eclipse version 
and in fact, doesn’t need to know about the workbench at all. Therefore, it is easy to test and 
reusable in any Eclipse version. In the following section we explain the basic idea based on the 
example of a handler implementation. 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  17/24 
 
 

 
A good example for the separation is the implementation of a handler.  
 
To implement a handler in Eclipse 3.x that is bound to a command, you need to implement the 
interface IHandler. Let’s look at a typical example handler in 3.x, which does something with the 
current selection. In this example, the handler checks if the current selection is of type 
“MailAccount”. If this is true, the handler checks if the user is already logged in and 
subsequently sends and receives mails. 
public​ Object​
​ execute​ (​
ExecutionEvent event​ )​throws​
​ ExecutionException {

ISelection currentSelection ​ =​HandlerUtil.​getCurrentSelection​ (​
event​
)​
;
if​
​ (​
​currentSelection ​ instanceof​ IStructuredSelection​ )​
{

Object​
​ firstElement ​ =​ ((​
​ IStructuredSelection​ )​currentSelection​)
.​
getFirstElement​ ()​
;
if​
​ (​
​firstElement ​ instanceof​ MailAccount​)​{

MailAccount account ​ =​ (​
​MailAccount​)​firstElement​ ;
if​
​ (​
!​
account.​ isLoggedIn​ ()){
account.​ logIn​()​
;
}

account.​ sendMails​ ()​;
account.​ recieveMails​ ()​
;
}

}

return​
null​
​ ;
}

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  18/24 
 
 

There are three major problems with this design: boilerplate code, lack of testability, and lack of 
re­usability. Let’s imagine that you would like to write a test case for this handler. You need to 
manually create an ExecutionEvent and also make sure that the HandlerUtil is available in your 
test environment. Since the selection in this case is not a plain field, but rather a property, you 
would need to look at the implementation of HandlerUtil.getCurrentSelection() to find out how to 
properly prepare your Mock ExecutionEvent. Even if you manage to create a test case, let’s 
imagine you want to trigger a timer­based mail synchronization, meaning that you want to 
directly call the execute method. In order to re­use the handler, you would again need to create 
an ExecutionEvent. If the handler is within your control, you will probably refactor at this time. 
However, the handler might be within a framework where you cannot refactor. 
The solution for this is pretty simple: we split the code into two methods. The first will deal with 
all workbench specific parts, i.e. unpacking the selection. The second method will execute the 
business logic itself and can, in this case, be static. 
public​ Object​
​ execute​ (​
ExecutionEvent event​ )​throws​
​ ExecutionException {

ISelection currentSelection ​ =​HandlerUtil.​getCurrentSelection​ (​
event​
)​
;
if​
​ (​
​currentSelection ​ instanceof​ IStructuredSelection​ )​
{

Object​
​ firstElement ​ =​((​
​ IStructuredSelection​ )​currentSelection​)
.​
getFirstElement​ ()​
;
if​
​ (​
​firstElement ​instanceof​ MailAccount​ )​{

synchronizeAccount​ ((​
MailAccount​)​firstElement​)​
;
}

}

return​
null​
​ ;
}

public​ static​
​ void​
​ synchronizeAccount​
(​
MailAccount account​
)​
{

if​
​ (​
!​
account.​isLoggedIn​ ()){
account.​logIn​()​
;
}

account.​sendMails​ ()​
;
account.​recieveMails​ ()​
;
}
With this design it is much easier to write a test case for the second method. Additionally, the 
method can be easily called from anywhere else, e.g. triggering the timer­based 
synchronization. Moreover, the code is easier to understand. As a next step, the second method 
can be moved out of the handler, for example, into a plugin which does not have any workbench 
dependencies. 
Applying the same design pattern to views will result in the same advantages. We have one 
class implementing the workbench specific parts and one class which can be a POJO. In the 
following example, the WorkbenchView does all workbench specific parts, including handling 
the current selection, while the POJOView is completely independent. 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  19/24 
 
 

public​
class​
​ WorkbenchView ​
extends​
ViewPart ​
{

private​
POJOView pojoView​
;

public​WorkbenchView​
()​
{

pojoView ​
=​new​
​ POJOView​
()​
;
}

@Override
public​ void​
​ createPartControl​ (​
Composite​ parent​)​{

pojoView.​createPartControl​(​
parent​)​
;
ISelectionService service ​=​(​
​ISelectionService​)​getSite​
()​
.​
getService​
(
ISelectionService.​
class​)​
;
service.​
addSelectionListener​(​new​ ISelectionListener​()​
{

@Override
public​ void​
​ selectionChanged​ (​
IWorkbenchPart part,
ISelection selection​ )​{

if​
​ (​
​selection ​instanceof​ IStructuredSelection​
)​
{

Object​
​ firstElement ​=​ ((​
​ IStructuredSelection​
)​
selection​
)
.​
getFirstElement​ ()​
;
pojoView.​ setInput​(​
firstElement​)​
;
}

}
})​;

@Override
public​void​
​ setFocus​()​
{

pojoView.​
setFocus​
()​
;
}

}
public​
class​
​ POJOView ​
{

private​
Text text​
;

public​ void​
​ createPartControl​
(​
Composite​
parent​
)​
{

text ​
=​new​
​ Text​
(​
parent, SWT.​NONE​
)​
;
}

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  20/24 
 
 

public​ void​
​ setFocus​
()​
{

text.​
setFocus​
()​
;

public​ void​
​ setInput​(​
Object​object​
)​
{

if​
​ (​
object​
!=​
null​
){
text.​
setText​
(​
object.​
toString​
())​
;
}

}

}
Again the POJOView is now very easy to understand, test and re­use. As an example, the 
POJOView could be embedded into a JFace Wizard. Until this point, we have not used any 
Eclipse 4 specific concepts, nor any dependency injection; the pattern can be used in plain 3.x. 
Its is a very general pattern which we recommend to follow in order to make your custom 
components more reusable and testable. 
As the wrapper classes (the one which implements the 3.x interface) always look pretty similar, 
it would be easy to provide a few generic implementations. We will introduce such a generic 
implementation later in this tutorial that uses dependency injection. 

POJOs in 3.x (with Dependency Injection)


If you separate workbench specific code and custom components as POJOs, as shown before, 
components are easier to reuse and to test, even in 3.x. However, there are still two 
disadvantages compared to developing a component for the Eclipse 4 Application Platform: 
1. The wrapper has to be manually implemented  
2. The implementation of the component cannot use dependency injection and therefore, is not 
ready to be used in Eclipse 4. 
 
Once your application is running on an Eclipse 4.x version there are solutions for this even if 
you still use the 3.x API (compatibility layer). That means, you can implement your POJO 
component as before, but additionally, you can use dependency injection and do not need to 
implement a wrapper to connect your POJO with the workbench. 
There are three ways to connect POJO views using dependency injection into a compatibility 
layer based application: 
1. Use the 3.x extension point (only available for views) 
2. Use fragments or processors 
3. Use the 3.x e4 bridge from the tools project 
 
The first option is available only for views since Luna. The existing 3.x extension point has been 
extended by the possibility to register “e4views”. This entry in the default extension point does 
not point to an implementation of IViewPart (3.x interface to be implemented by view), but it 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  21/24 
 
 

points to a POJO class. This POJO class can use all the Eclipse annotations for dependency 
injection. The following example shows the two extensions available to register views. The first 
one is a tranditional 3.x View implementing IViewPart. The second extension registers a POJO 
implementation using dependency injection. It will be added to the workbench, just like any 
other view. 
 
 <extension 
         point="org.eclipse.ui.views"> 
      <view 
            name="View" 
            class="myrcpapp.3xViewImplementation" 
            id="myRCPApp.view"> 
      </view> 
      <e4view 
            class="myrcpapp.POJOViewImplementation" 
            id="myRCPApp.e4view" 
            name="E4View" 
            restorable="true"> 
      </e4view> 
   </extension> 
  
 
 
The second option is to use​  processors and fragments​  to add elements to the application model 
created by the compatibility layer. This option is very appealing because not only can you use 
dependency injection for the implementation, but you can also model the things you want to 
contribute as elements in the fragment. However, there are currently still some timing problems. 
When processors and fragments are being processed, the compatibility layer has not yet 
created the complete application model. (See this bug report. 
(​https://bugs.eclipse.org/bugs/show_bug.cgi?id=376486​ ). Therefore, this option might work for 
handles and views, but currently it doesn’t work for editors or things which extends perspectives 
defined by the IDE. 
The third solution is provided by the 3.x e4 bridge from the e4 tools project. The plugin basically 
provides generic wrapper classes, which can be used in a 3.x application. The wrapper classes 
allow the definition of a second class, which is a POJO, and implements the corresponding 
component. The solution follows the same pattern we describe before, but works in a generic 
way and supports dependency injection. At the time of writing, implementations for Views, 
Editors, and Handlers are available. To create the 3.x workbench wrapper, one simply inherits 
from the respective type, e.g. from DIViewPart to implement a View. The wrapper class is 
almost empty. It only has to specify the POJO class that implements the component. 
public​
class​
​ ExampleViewWrapper ​
extends
DIViewPart​
{

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  22/24 
 
 

public​
ExampleViewWrapper​ ()​
{

super​
​ (​
ExampleView.​
class​
);​
}
}
This class is now registered using the view’s extension point as is usual in 3.x (not with the 
previously mentioned e4view extension). 
The implementation of the view itself can be a POJO and dependency injection can therefore be 
used. In addition to being quite convenient to develop, in case the component is migrated to e4, 
it is ready to be used without any adaptation. In this case, you can remove the wrapper and the 
extension to integrate the POJOView into the application model. As you can see, the view can 
use all features of dependency injection, including injection into the current selection. 
public​ class​
​ ExampleView ​ {
private​ Label​
​ label​
;
@Inject
public​ ExampleView​ (​
Composite​
parent​
){
label ​
=​new​
​ Label​
​ (​
parent, SWT.​
NONE​)​
;
label.​
setText​
(​
"Hello World"​)​
;
}

@Inject
public​ void​
​ setInput​(​
@Optional
@Named​ (​
IServiceConstants.​ ACTIVE_SELECTION​
)​
Object​
input​
){
if​
​ (​
input​
==​ null​){
return​
​ ;
}

label.​
setText​(​
input.​
toString​
())​
;
}
}
To understand how this works, we look at the simplest case, a wrapper for a Handler. To 
simplify the example, we will ignore the annotation @CanEnable for now. The DIHandler needs 
to implement the 3.x IHandler interface allowing it to be registered with the handler extension 
point, as is common in 3.x. Additionally, the DIHandler needs to know about the POJO class 
that it wraps. This POJO class should be instantiated by the wrapper. To do this, we use the e4 
ContextInjectionFactory. As the application is running on the compatibility layer, we can retrieve 
the EclipseContext as a service and use it to create the class. This way, all fields expected by 
the Handler are being injected (as is standard in e4). 
public​
class​
​ DIHandler ​
extends​
AbstractHandler {

private​
Class clazz​
;
private​
C component​ ;

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  23/24 
 
 

public​ DIHandler​ (​
Class clazz​)​
{

this​
​ .​
clazz​
=​
​ clazz​;
IEclipseContext context ​ =​ getActiveContext​()​
;
component ​ =​ ContextInjectionFactory.​ make​(​
clazz, context​
)​
;
}
private​ static​
​ IEclipseContext getActiveContext​ ()​{

IEclipseContext parentContext ​ =​ (​
​IEclipseContext​)
PlatformUI.​ getWorkbench​ ()​
.​
getService​(
IEclipseContext.​ class​)​
;
return​
​ parentContext.​ getActiveLeaf​ ()​
;
}
The only missing piece now is the implementation of the execute method. It simply uses the 
InjectionFactory again to invoke the method of the POJO, which is marked with @Execute: 
public​ Object​
​ execute​ (​
ExecutionEvent event​
)​
throws​
​ ExecutionException {

return​
​ ContextInjectionFactory.​
invoke​
(​
component, Execute.​
class​
,
getActiveContext​())​
;
}
This DIHandler is not very complex and allows wrapping POJO handlers into the 3.x workbench. 

Conclusion
We described different approaches for a soft migration from 3.x to the Eclipse 4 programming 
model. We started with the concept of separating the implementation of custom UI components 
and workbench specific classes. This improved the re­usability and the testability of the 
components. It is a pattern you should follow, even if you never want to migrate to Eclipse 4. It 
can be used with or without dependency injection. When using dependency injection, there are 
three ways to integrate the POJOs into the 3.x workbench. For views, the 3.x extension point 
allows you to directly register them. For other elements, you will need to use the 3.x e4 bridge 
provided by the e4 tools or fragments.  
 

 
 
Copyright by EclipseSource München GmbH ­ 2015 ­ Jonas Helming ­ ​
[email protected]  24/24 
 

You might also like