Define access restriction on plugin

In Eclipse it seems to be common practice to define interfaces and hide a concrete implementation in a package under *.internal.*. The actual hiding though is not result of the word „internal“ in the package name but must be specified in the MANIFEST.MF with the exported packages.
There are also further possibilities that can be engaged. For example you can define a package a friend to another package(es) so that only these can access the classes within.

Manifest.MF
Bundle-SymbolicName: example
Export-Package:
com.example.public, // Anyone can access com.example.public if imported
com.example.test;x-internal:=true, // This is marked as internal, but can be used
com.example.impl;x-friends:=com.example.other, // Only com.example.other should access it

This is not part of the OSGi Standard but the Equinox reference implementation.
For further reference see the Article at EclipseZone.

Plugin gets stuck

While working on a new plugin I tried to reuse components, that already exist.
While testing the plugin froze. You could see it in the debug view by stepping to the reused component. There where no exceptions that tell you anything. Suddenly I had the idea that in the eclipse environment that I started to test the plugin might have something in the error log. Bingo: NoClassDefFoundException. But how could the plugin compile if the resource is not available? The answer is quite simple: I added the needed resource file to the buildpath instead to the plugin dependencies. Therefore at compile time the resource could be found but the plugin knew nothing of the needed resource. When building a plugin never add something needed to the buildpath, add it to the dependencies. Doing this the plugin worked as desired

Getting started with PHP Class Generator Plugin

The Eclipse plugin PHP Class Generator is now about a month up on Eclipse Plugin Central. It was now brought to my attention (thanks Tyler) that documentation is not exactly missing but at least hard to find and you have to know where and how to look. This article should help to shed light into the dark.
„Getting started with PHP Class Generator Plugin“ weiterlesen

Eclipse Wizard Plugin erstellen

Eclipse stellt bereits einen Wizard zur Verfügung, um eine Wizard zu erstellen: Über New->Plug-in Development->Plug-in Project ein neues Projekt anlegen. Auf der Folgeseite habe ich dann als Target Eclipse (in Version 3.3) angegeben; das OSGi Framework habe ich nicht ganz durchschaut, jedenfalls war mein fertiges Plug-in dann nicht kompatibel. new Plugin step 3 of 5
Auf der 3 Seite sind dann die Eckdaten zu vergeben: Plug-in ID üblicherweise der package name, Version ist selbsterklärend, der Plug-in Name hat nur bezeichnenden Charakter, sollte aber sprechend ausdrücken, wofür das Plug-in steht. Der Plug-in Provider ist üblicherweise ein Teil der Webadresse z.B. eclipse.org, ibm.com oder sahits.ch. Der Activator wird benötigt, um das Plug-in zu aktivieren.
new Plugin step 4 of 5
Auf der folgenden Seite kann zwischen den verschiedenen Plug-ins ausgewählt werden. Für einen Wizard benötigen wir ein „Plug-in with multi-page editor“; Mit Editor ist letztentlich die Grafische Oberfläche des Wizards gemeint wo die Eingaben gemacht werden, wie auf gerade dieser Schritt. Multi-page besagt lediglich, dass der Wizard aus mehreren Schritten bestehen kann, aber nicht muss.
Auf den beiden letzten Seiten werden dann die Informationen für die zu erstellenden Klassen gemacht.
Nach dem Abschluss hat man bereits ein funktionsfähiges Plug-in. Um es auszutesten wählt man das Projekt an und Run As->Eclipse Application. Dies startet eine zweite Eclipse Instanz mit eigenem Workspace (ein Workspace kann gleichzeitig nur von einer Eclipse Instanz benutzt werden). Hier kann der Wizard über New->Other->Other gestartet werden.
Nun geht es daran, den Wizard mit eigenem Code zu fällen. Ein guter Einstiegspunkt ist Eclipse Plugins Exposed, Part 1: A First Glimpse
Hat man die eigene Funktionalität integriert gibt es noch etwas Schönheitspflege zu machen:

  1. Wo in der Liste soll der Wizard erscheinen? Dies wird im plugin.xml im attribut category des tags wizard geregelt. Keine Angabe verfrachtet das Element in den Ordner other. Ein String bringt es in einem Ordner mit diesem Namen unter. Aber Achtung: Wenn bereits ein Ordner mit demselben Namen existiert, gibt aller Wahrscheinlichkeit nach einen zweiten Ordner. Soll der Wizard in einem anderen Ordner erscheinen ist hier die Klasse des Wizards einzutragen.Plugin.xml
  2. Das Plug-in soll ja nicht nur einer Eclipse Instanz verfügbar sein, sondern beim Starten verfügbar sein. Dazu muss das Plug-in in das Verzeichnis eclipse/plugins. Dies jedoch nicht in der Form, wie im Projekt. Für das Plug-in wird das plugin.xml, ein jar-File der Klassen, das Verzeichnis icons und eventuell das Verzeichnis icons, zusätzlich benötigte Bibliotheken und andere Resourcen benötigt.
    Dies gibt man im Plug-in oder Manifest Editor im Tab Build ein.
    Plugin.xml Build
    Unter Runtime Information gibt man den Namen des jar files an, das erstellt werden soll. In Binary Build wird angegeben, was alles im Build enthalten sein soll. Unter Extra Classpath Entries werden zusätzliche Bibliotheken angegeben.
    Um den aktuellen Build auszuführen gibt es mehrere Möglichkeiten: 1. Über Export->Plug-in Development->Deployable plugins and features. Dies erstellt jedoch nur ein jar-file der Klassen mit dem angegebenen Namen in einem plugins Verzeichnis. 2. Wertvoller aber auch nicht ganz optimal ist der Weg über ein Ant build script. Um das build.xml zu erhalten muss das plugin.xml angewählt sein, dann PDE Tools->Create Ant Build File. Dann kann zuerst das Default Target ausgeführt werden, um das jar-File zu erhalten, sodann das target zip.plugin was ein Zip-Archiv des Ordners plugin-ID_Version erstellt und alles unter Binary Build angegebene enthält. Leider aber zusätzlich zwei Zip-Files mit den Sourcen und das Verzeichnis bin. (Dies gilt zumindest für Eclipse 3.3). Also muss hier von Hand aussortiert werden.

Das Ganze ist nicht ganz ohne deshalb hier noch ein paar Tipps:

  • Das Plug-in wird nicht geladen/aktiviert: Erst mal schauen ob das Plug-in verfügbar ist unter Help->Ablut Eclipse SDK->Plug-in Details. Um das Problem zu eruieren kann es sinnvoll sein im Manifest das LacyLoad auf false zu setzen. Dies bewirkt, dass das Plug-in beim Start von Eclipse geladen wird. Ein Blick ins Error log (Window->Show View->Error log) enthällt das Problem
  • Im Error log erscheint die Meldung „plugin does not have valid identifier“ oder „plugin does not have valid version“. Hier habe ich mir sagen lassen, dass dies mit einer JRE < 1.5 vorkommen kann. Mein Problem war ein anderes: Das Verzeichnis META-INF fehlte.
  • Wenn der Wizard gestartet werden soll erscheint die Fehlermeldung „Error loading new wizard …“ Zum einen kann es sein, dass im plugin.xml die falsche Klasse angegeben ist, oder dass das jar-file im Classpath des Plug-ins fehlt (META-INF/Manifest.mf)
  • Wenn alles nichts nützt Eclipse von der Konsole mit eclipse -clean starten. Wenn dies auch nicht funktioniert alles im Verzeichnis eclipse/configuration/.settings/ löschen.