Inkompatibilitäten zwischen Eclipse 3.1 und 3.2

Eclipse wurde in inkompatibler Weise von 3.1 zu 3.2 verändert, was sich auf die Plug-ins auswirkt. Die folgenden Abschnitte beschreiben die Bereiche, die geändert wurden, und enthalten Anweisungen für die Migration eines Plug-ins aus Version 3.1 auf Version 3.2. Beachten Sie, dass Sie nur hier nachsehen müssen, wenn Sie Probleme beim Ausführen Ihres Plug-ins aus Version 3.1 auf Version 3.2 haben.

  1. Ressourcen befinden sich nicht mehr unbedingt im lokalen Dateisystem
  2. API-Änderungen bei MultiPageEditorSite
  3. Inhaltsänderungen in der Datei "config.ini"
  4. Inhaltsänderungen bei über JNLP implementierten Anwendungen
  5. Explizite Aufrufe von "Bundle.start()" erzwingen Aktivierung des Produktpakets beim nächsten Neustart
  6. Unterstreichungszeichen wird in Versionsnummern von Plug-ins nicht mehr durch Bindestrich ersetzt

1. Ressourcen befinden sich nicht mehr unbedingt im lokalen Dateisystem

Betroffen:Clients der API IWorkspace, die davon ausgehen, dass Ressourcen im lokalen Dateisystem gespeichert sind.

Beschreibung: Vor Eclipse 3.2 gab es für jede vorhandene Schnittstelle IResource eine entsprechende Datei bzw. ein Verzeichnis in einem Dateisystem, auf das durch java.io.File zugegriffen werden konnte. In Eclipse 3.2 wurde eine Unterstützung für das Erstellen von Ressourcen hinzugefügt, deren Inhalt in einem beliebigen Dateisystem gespeichert sein kann. Ressourcen, die diese Unterstützung verwenden, können nicht mehr direkt als java.io.File dargestellt werden.

Erforderliche Aktion: Die alte Methode IResource.getLocation() gibt den Pfad einer Ressource im lokalen Dateisystem zurück. Diese Methode gibt bei Ressourcen, die nicht im lokalen Dateisystem gespeichert sind, Null zurück. Die meisten Aufrufe von getLocation() erfolgten, um ein Exemplar von java.io.File zu erhalten, das nicht mehr für Ressourcen verwendet werden kann, die nicht im lokalen Dateisystem gespeichert sind.

Das neue Plug-in org.eclipse.core.filesystem stellt eine generische Dateisystem-API bereit, die anstelle von java.io.File verwendet werden kann. Ein Exemplar von org.eclipse.core.filesystem.IFileStore stellt insbesondere die meisten derjenigen Methoden bereit, die bei java.io.File verfügbar waren. Der folgende Code-Ausschnitt ruft ein Exemplar von IFileStore für eine bestimmte Ressource ab:

   IResource resource = ...;//some resource
   IFileStore store = EFS.getStore(resource.getLocationURI());

Die folgende Tabelle enthält funktional entsprechende Methoden bei IFileStore für Operationen, die normalerweise mit java.io.File ausgeführt werden:

java.io.FileIFileStore
deletedelete
getNamegetName
getParentgetParent
listchildNames
mkdirmkdir(EFS.SHALLOW, null)
mkdirsmkdir(EFS.NONE, null)
renameTomove
new FileInputStream(file)openInputStream
new FileOutputStream(file)openOutputStream

In der API IFileStore werden die meisten Informationen zu einer Datei in einer Struktur namens IFileInfo gespeichert, die durch den Aufruf von IFileStore.fetchInfo() erhalten wird. Dieser Entwurf ermöglicht gegenüber Code, der java.io.File verwendet, eine größere Optimierung, da viele Attribute über eine Datei häufig mit einem einzigen Aufruf des Dateisystems abgerufen werden können. Bitte beachten Sie, dass die Informationen in einer Struktur IFileInfo veraltet sind, sobald die zu Grunde liegende Datei geändert wurde. Exemplare sollten daher nur so lange beibehalten werden, wie sie benötigt werden. Die folgende Liste enthält einige Methoden aus java.io.File, für die es bei IFileInfo funktional entsprechende Methoden gibt:

java.io.FileIFileInfo
canWriteisReadOnly
existsexists
getNamegetName
isDirectoryisDirectory
isFile!isDirectory()
isHiddenisHidden
lastModifiedgetLastModified
lengthgetLength
setLastModifiedsetLastModified
setReadOnlysetAttribute(EFS.ATTRIBUTE_READ_ONLY, true)

Konkret kann Code, der zuvor java.io.File.exists() aufgerufen hat, nun IFileStore.fetchInfo().exists() aufrufen. Wenn eine Struktur IFileInfo geändert wird, muss das Ergebnis mit der Methode IFileStore.putInfo wieder gespeichert werden. Der folgende Ausschnitt wechselt beispielsweise das Lesezugriffsattribut einer Datei:

   IFileStore store = ...;//some file store
   IFileInfo info = store.fetchInfo();
   boolean readOnly = info.getAttribute(EFS.ATTRIBUTE_READ_ONLY);
   info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, !readOnly);
   store.putInfo(info, EFS.SET_ATTRIBUTES, null);

IProjectDescription.getLocation()

Wie die Methode getLocation() kann auch die Position einer Projektbeschreibung nicht mehr im lokalen Dateisystem angesiedelt sein. Mit der Methode IProjectDescription.getLocationURI() können Sie die Position einer Ressource in einem beliebigen Dateisystem abrufen.

Im lokalen Cache speichern

Manche Clients benötigen unbedingt eine lokale Darstellung einer Datei. Beispielsweise kann es sein, dass ein natives Tool für diese Datei gestartet wird oder dass nicht Eclipse-fähige Bibliotheken verwendet werden, die ausschließlich Dateisystemressourcen verarbeiten können (z. B. java.util.zip.ZipFile). In solchen Fällen können Sie "IFileStore" anweisen, eine zwischengespeicherte lokale Kopie des Inhalts zurückzugeben:

   IFileStore store = ...;//some file store
   //see if it can directly be represented as a local file
   java.io.File local = store.toLocalFile(EFS.NONE, null);
   //if not, ask for a cached local copy of the file
   if (local == null)
      local = store.toLocalFile(EFS.CACHE, null);

Bitte beachten Sie, dass eine zwischengespeicherte Kopie einer Datei nach ihrem Abruf nicht mehr mit dem Dateisystem synchron ist, aus dem sie ursprünglich stammte. Bei einer Änderung der zwischengespeicherten Kopie wird die zu Grunde liegende Datei nicht geändert.

Ordnungsgemäß verarbeitete Fehler

Bei Clients, die Ressourcen außerhalb des lokalen Dateisystems nicht verarbeiten können, kann es dennoch sinnvoll sein, den Code so anzupassen, dass Fehler ordnungsgemäßer verarbeitet werden. Clients können feststellen, ob sich eine Ressource im lokalen Dateisystem befindet und dann entweder die Ressource ignorieren oder den Benutzer warnen, wenn sie eine Ressource finden, die sie nicht verarbeiten können. Um festzustellen, ob sich eine Ressource im lokalen Dateisystem befindet, müssen Sie das Schema für ihr Dateisystem ermitteln. Dies können Sie folgendermaßen aus einer Ressource abrufen:

   IResource resource = ...;//some resource
   URI uri = resource.getLocationURI();
   if (uri != null && EFS.SCHEME_LOCAL.equals(uri.getScheme())) {
      //file is in local file system
   } else {
      //file is not in the local file system
   }

Falls ein Exemplar von IFileStore verfügbar ist, können Sie das Schema wie folgt abrufen:

   IFileStore store = ...;//a file store
   store.getFileSystem().getScheme();

2. API-Änderungen an MultiPageEditorSite

Betroffen: Clients, die MultiPageEditorSite.progressStart() oder MultiPageEditorSite.progressEnd() aufrufen.

Beschreibung: Während der Entwicklung von Eclipse 3.0 wurden diese Methoden im Rahmen der Arbeit an der Fortschrittsunterstützung hinzugefügt. Vor der Freigabe der Version 3.0 wurde die Art der Verarbeitung für den Fortschritt geändert, und diese Methode war nicht mehr erforderlich. Aufgrund von Programmiererfehlern verblieben diese allgemein zugänglichen Methoden jedoch im Release 3.0. Diese beiden Methoden haben in keinem Eclipse-Release je eine Funktion ausgeführt und wurden daher gelöscht.

Erforderliche Aktion: Clients, die MultiPageEditorSite.progressStart() oder MultiPageEditorSite.progressEnd() aufrufen, sollten zur Verwendung von IWorkbenchSiteProgressService übergehen.

3. Inhaltsänderungen in der Datei "config.ini"

Betroffen: Clients, die eine angepasste Datei "config.ini" verwenden und die Anwendung auf Version 3.2 migrieren.

Beschreibung: Vor Version 3.2 war für Produktpakete des Typs "osgi.bundle" in der Datei "config.ini" normalerweise der Wert org.eclipse.core.runtime@2:start, org.eclipse.update.configurator@3:start enthalten. Aufgrund eines Refactorings der Laufzeit muss dieser Wert aktualisiert werden, damit die Anwendung erfolgreich gestartet werden kann.

Erforderliche Aktion: Ändern Sie den Wert von Produktpaketen des Typs "osgi.bundle" so, dass org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start enthalten ist.

4. Inhaltsänderungen bei über JNLP implementierten Anwendungen

Betroffen: Clients, die RCP-Anwendungen implementieren und einen Wert für "osgi.bundles" angeben.

Beschreibung: Vor Version 3.2 war für Produktpakete des Typs "osgi.bundle" in der JNLP-Hauptdatei normalerweise der Wert org.eclipse.core.runtime@2:start, org.eclipse.update.configurator@3:start enthalten. Aufgrund eines Refactorings der Laufzeit muss dieser Wert aktualisiert werden, da andernfalls Ausnahmebedingungen des Typs NullPointerException ausgelöst werden, die ein Starten der Anwendung verhindern.

Erforderliche Aktion: Ändern Sie den Wert von Produktpaketen des Typs "osgi.bundle" so, dass org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start enthalten ist.

5. Explizite Aufrufe von "Bundle.start()" erzwingen Aktivierung des Produktpakets beim nächsten Neustart

Betroffen: Clients, die Bundle.start() aufrufen.

Beschreibung: In Eclipse wird für ein Produktpaket durch die Verwendung des Headers Eclipse-LazyStart (bzw. des veralteten Headers Eclipse-AutoStart) das verzögerte Starten angegeben. In Eclipse 3.1 kennzeichnete die Methode org.osgi.framework.Bundle.start() Produktpakete mit verzögertem Start nicht als permanent gestartet. Da Produktpakete mit verzögertem Start in keinem Fall als permanent gestartet gekennzeichnet wurden, wurden sie auch bei einem Neustart von Eclipse nie automatisch gestartet. Das Javadoc für Bundle.start() besagt, dass beim Aufruf der Methode Folgendes stattfinden muss:

"Persistently record that this bundle has been started. When the Framework is restarted, this bundle must be automatically started." (Der Start dieses Produktpakets muss als permanent vermerkt werden. Wenn das Gerüst erneut gestartet wird, muss dieses Produktpaket automatisch gestartet werden.)

In Eclipse 3.2 wurde die Methode Bundle.start() korrigiert, damit auch Produktpakete mit verzögertem Start korrekt als permanent gestartet gekennzeichnet werden. Diese Korrektur war erforderlich, um die Spezifikation des OSGi-Frameworks einzuhalten. Aufrufende Module von Bundle.start() erzwingen infolgedessen den Start des Produktpakets bei einem Neustart von Eclipse. Dieses Verfahren gilt generell als ungeschickt, da es bei jedem Neustart zur Aktivierung von nicht benötigten Produktpaketen führt. In manchen Fällen kann dies unerwartete Ergebnisse nach sich ziehen (siehe beispielsweise Programmfehler 134412).

Erforderliche Aktion: Clients von Bundle.start() müssen ermitteln, ob ein Produktpaket bei jedem Neustart permanent aktiviert werden soll. Wenn dies nicht der Fall ist, sollten die Clients eine andere Methode zur Aktivierung des Produktpakets suchen. In den meisten Fällen können Aufrufe von Bundle.start() einfach dadurch vermieden werden, dass die verzögerte Aktivierung des Zielproduktpakets möglich ist, wenn Klassen daraus geladen werden. Es gibt wenige Szenarien, bei denen eine aggressive Aktivierung eines Produktpakets mit verzögertem Start erforderlich ist, das Produktpaket jedoch nicht für die Aktivierung bei einem Neustart gekennzeichnet sein darf. Solche Szenarien sollten mit Bundle.loadClass() eine Klasse aus dem Produktpaket laden, die aktiviert werden muss, statt Bundle.start() aufzurufen.

6. Unterstreichungszeichen wird in Versionsnummern von Plug-ins nicht mehr durch Bindestrich ersetzt

In Eclipse 3.0 wurde die Verwendung eines Unterstreichungszeichens (_) im Qualifikationsmerkmalssegment einer Versions-ID zwar nicht unterstützt, aber auch nicht verhindert. Falls die Versions-ID eines Plug-ins im Qualifikationsmerkmal ein Unterstreichungszeichen enthielt, wurde dieses Zeichen beim Export des Plug-ins in das Dateisystem und bei der Installation des Plug-ins über eine Update-Site in einen Bindestrich umgewandelt.
In Eclipse 3.1 wurden die Regeln für zulässige Zeichen in Qualifikationsmerkmalen gelockert und ließen das Unterstreichungszeichen zu. Wenn ein anderslautendes Plug-in exportiert oder installiert wurde, wurde daher der ursprüngliche Stand des Qualifikationsmerkmals nicht geändert. Diese geringfügige Änderung wurde im Handbuch für die Migration von 3.0 auf 3.1 versehentlich nicht behandelt. Bei Eclipse 3.2 bleibt die Kompatibilität mit Eclipse 3.1 erhalten. Plug-ins, bei denen das Qualifikationsmerkmal der Version ein Unterstreichungszeichen enthält, sollten daher beim Umgang mit älteren Plug-in-Versionen (sowohl beim Export als auch auf der Update-Site) die oben beschriebenen Änderungen beachten. Dies bedeutet beispielsweise, dass Plug-in-Provider, die alte Versionen ihrer Plug-ins auf einer Update-Site bereitstellen, sicherstellen müssen, dass der Name im Dateisystem mit dem Namen des Plug-ins übereinstimmt.