Friday, July 30, 2010

PDE Good Practices: #7 Keep build.properties synced

We often land up in situations like "it was working in my workspace but exported plugins are behaving differently". An important thing to notice is that workspace is build considering the project classpath settings. However, the Export wizard or headless build does not have access to it. They reply on build.properties file. Thus it is very important to keep it in sync with the project settings. Eclipse Helios (3.6) added a bunch of preferences to help you do just that.


I would even recommend having project specific preferences enabled whenever possible. This will ensure all developers are reported for problems and their workspace settings doesn't have them ignored.

PDE Good Practices: #6 Share target definitions

Always have your target definitions in a project instead. This way

  1. it can be added to source control repository and changes to it can be tracked.
  2. all the other members who wish to work with that code can share it and thus compile against the same target. This will keep everyone on same page.

Thursday, July 22, 2010

PDE Good Practices: #5 Prefer target over workspace

Remember it is a 'good practice' and not necessarily the best suited to your needs. So unless you are sure what you are doing, it is advisable to keep all the dependent plug-ins in target. Check-out only the those which you need to modify, The benefits are

  • A small workspace is easier to follow
  • Even a full build will be much faster
  • Since target platform can be shared, you can be sure that you are build against the same exact version as your peers
  • Launch will be faster

If you miss that Types are not showing up in the searches, use PDE preference to add all the target plug-ins to the Java search.


Tuesday, July 20, 2010

PDE Good Practices: #4 Use startup code carefully

Be very careful when adding code to
  1. Plug-in load and constructor



  2. org.eclipse.ui.startup extension

These places have a big impact on application startup time. Also note that the if there are many plug-ins dependent on one plug-in and that plug-in is doing something on load (which it shouldn't be) then it may be delaying the loading of the whole stack.

Headless Build for Beginners - part III

Automated building an RCP application from a product configuration file

Most of this post contains same info as the eclipse help page with same heading.

Creating a product configuration file is easy. Check the eclipse help page explains it well. Assuming the our product config example.product looks like this and resides in a plug-in com.example.product.




Basic Setup
We will need 3 directory paths
  1. where the features and plug-ins to be build will reside. We will call it buildDirectory.
  2. where the build configuration file (build.properties) will reside. We will call it buildConfiguration.
  3. where the eclipse installation resides. We will call it baseLocation.
Now to prepare these directories
  1. Copy the features and plug-ins in side the buildDirectory. Ideally this will be a source checked out from the version control system. Custom ant tasks can be used to automate that. For this example, the directory shall look like this
  2. <buildDirectory>
           plugins/
                  com.example.helloworld
                  com.example.product
                         example.product
           features/
                  com.example.helloworld.feature


  3. Copy build.properties file from baseLocation/plugins/org.eclipse.pde.build_<version>/templates/headless-build to buildConfiguration folder. This file will configure the build and the output.
  4. Now we need to edit this build.properties file and fill in the parameters
    1. product=C:/build/buildDirectory/plugins/com.example.product/example.product
    2. This entry shall point to the product configuration file. The features/plugins mentioned in this file will only be picked for the build but searched in buildDirectory and baseLocation.
    3. archivePrefix=HelloWorld
    4. The archivePrefix is the name of the Folder under which the product will reside.
    5. configs=win32, win32, x86
    6. The configs shall point to the platforms for which product has to be build. The eclipse mentioned at baseLocation should have RCP Delta Pack. Without the delta pack, the build wont be able to create product for other platforms. Also, when troubleshooting for missing config or launch files, ensure that right version of delta pack is installed.RCP Delta Pack is build along with SDK so the same version shall be used. I am building only for windows that is that the configs entry is for only win32. For building other platforms, uncomment the required platforms. The platforms are delimited using & \.
    7. buildDirectory=C:/build/buildDirectory
    8. This will the buildDirectory we setup above.
    9. buildType=I
    10. I is for Integration build, N for Nightly, M for Milestone, S for ...I dunno. But you got the point.
    11. buildId=ExampleProductBuild
    12. This will name the build archive.
    13. base=C:/
      baseLocation=${base}/eclipse
    14. The base is the location which contains the eclipse installation (with RCP Delta Pack).
Running and understanding output

The build will be invoked as before

java -jar <eclipse-installation-path>\plugins\org.eclipse.equinox.launcher_<version><qualifier>.jar -application org.eclipse.ant.core.antRunner -buildfile <eclipse-installation-path>\plugins\org.eclipse.pde.build_<version><qualifier>\scripts\productBuild\productBuild.xml -Dbuilder=c:\build\buildConfiguration

example

java -jar c:\eclipse\plugins\org.eclipse.equinox.launcher_1.1.0.v20100507.jar -application org.eclipse.ant.core.antRunner -buildfile c:\eclipse\plugins\org.eclipse.pde.build_3.6.0.v20100603\scripts\productBuild\productBuild.xml -Dbuilder=c:\build\buildConfiguration

The output will look like this

I.ExampleProductBuild
│   ExampleProductBuild-win32.win32.x86.zip

└───compilelogs
    └───plugins
        └───com.example.helloworld_1.0.0.201007191243
                @dot.log


The folder I.ExampleProductBuild will contain the build logs and the product build ExampleProductBuild-win32.win32.x86.zip. If we had chosen other configs they too will appear here in separate zip (or whichever format we specify).

Thursday, July 8, 2010

PDE Good Practices: #3 Lazy-loading and Singleton plug-ins

Lazy Loading

When a plug-in is marked for lazy loading it is NOT loaded until it is needed. This helps in keeping the memory footprint of application small as possible.

A plug-in can be marked for lazy loading by checking the 'Activate this plug-in when one of its classes is loaded' checkbox on the Manifest editor overview page. This create the following entry in the Manifest.MF file.

Bundle-ActivationPolicy: lazy

Singleton plug-ins

It is preferable to use singleton plug-ins unless you know what you are doing. If a plug-in exposes extension points then it has to be singleton. But if not, it is still advisable to keep them singleton. This would ensure only one version of the plug-in is loaded at a time and generally its the latest one (unless version bound).

A plug-in can be made singleton by checking the 'This plug-in is a singleton" checkbox on the manifest editor overview page.

OSGi environments generally prefer non-singleton plug-ins as they can be dynamically installed.





Thursday, July 1, 2010

PDE Good Practices: #2 Externalize bundle strings

Externalize all bundle strings.
  • Use ‘Usage of non-externalized strings’ preference




  • Enabling the preference marks all the strings that should be externalized.

  • Use 'Externalize Strings Wizard' to externalize the strings


  • 'Bundle-Localization' entry in Manifest points to the properties file containing the externalized strings.


The value 'plugin' for 'Bundle-Localization' entry means that there will be a 'plugin.properties' file in the plugin root containing the externalized strings e.g. '%Bundle-Name'. 

PDE Good Practices: #1 Separation of Concerns

  • Do not create monolithic plug-ins.
  • A plug-in is used to group the code into a modular, extendable and sharable unit. 
  • Prefer having  separate plug-ins for Core, UI, Doc, etc 
  • Separate the platform/locale code into fragments.
  • Put related plug-ins under same feature.