Platforma Eclipse byla podrobena změnám, jež zakládají nekompatibilitu verzí 3.1 a 3.2, která ovlivňuje moduly plug-in. Následující položky popisují oblasti, které se změnily, a poskytují pokyny pro migraci modulů plug-in pro verzi 3.1 do verze 3.2. Máte-li problémy se spuštěním svého modulu plug-in verze 3.1 ve verzi 3.2, věnujte pozornost následujícímu textu.
Co je ovlivněno:Klienti rozhraní API IWorkspace
, kteří předpokládají, že prostředky jsou uloženy v lokálním systému souborů.
Popis:
Před verzí Eclipse 3.2 měl každý stávající IResource
odpovídající soubor nebo adresář v systému souborů přístupném pomocí java.io.File
. Ve verzi Eclipse 3.2 byla přidána podpora pro vytváření prostředků, jejichž obsah je uložen v libovolném zálohujícím systému souborů. Prostředky používající tuto podporu již nemohou být reprezentovány přímo jako java.io.File.
Nezbytná akce: Původní metoda IResource.getLocation() vrací cestu prostředku v lokálním systému souborů. V případě prostředků, které nejsou uloženy v lokálním systému souborů, vrací tato metoda hodnotu null. Většina volajících metody getLocation() volají tuto metodu s cílem získat instanci java.io.File. Tu již nelze používat pro prostředky, které nejsou uloženy v lokálním systému souborů.
Nový modul plug-in org.eclipse.core.filesystem nabízí generické rozhraní API systému souborů, které lze používat místo java.io.File. Většinu stejných metod, které jsou dostupné v java.io.File, poskytuje zejména instance org.eclipse.core.filesystem.IFileStore. Následující úsek kódu získá instanci IFileStore pro daný prostředek:
IResource resource = ...;//některý prostředek IFileStore store = EFS.getStore(resource.getLocationURI());
Následující tabulka nabízí ekvivalentní metody v IFileStore pro operace prováděné obvykle pomocí java.io.File:
java.io.File | IFileStore |
---|---|
delete | delete |
getName | getName |
getParent | getParent |
list | childNames |
mkdir | mkdir(EFS.SHALLOW, null) |
mkdirs | mkdir(EFS.NONE, null) |
renameTo | move |
new FileInputStream(file) | openInputStream |
new FileOutputStream(file) | openOutputStream |
V rozhraní API IFileStore je většina informací o souboru uložena ve struktuře nazývané IFileInfo, získané voláním IFileStore.fetchInfo(). Toto uspořádání umožňuje větší optimalizaci oproti kódu využívajícímu java.io.File, protože mnoho atributů souboru lze často získat jediným voláním systému souborů. Uvědomte si, že informace v IFileInfo budou zastaralé, pokud dojde ke změně základního souboru, proto by měly být instance uchovávány pouze na nezbytně nutnou dobu. Některé metody vjava.io.File, které mají svůj ekvivalent v IFileInfo:
java.io.File | IFileInfo |
---|---|
canWrite | isReadOnly |
exists | exists |
getName | getName |
isDirectory | isDirectory |
isFile | !isDirectory() |
isHidden | isHidden |
lastModified | getLastModified |
length | getLength |
setLastModified | setLastModified |
setReadOnly | setAttribute(EFS.ATTRIBUTE_READ_ONLY, true) |
Konkrétní příklad: Kód, který předtím volal java.io.File.exists(), může nyní volat IFileStore.fetchInfo().exists(). Když dojde k úpravě IFileInfo, výsledek je třeba uložit zpět pomocí metody IFileStore.putInfo. Tento úsek kódu například převrací atribut Pouze pro čtení u souboru
IFileStore store = ...;//nějaké uložení souboru 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);
Stejně jako v případě metody getLocation(), umístění popisu projektu již nemusí být v lokálním systému souborů. Metodu IProjectDescription.getLocationURI() lze používat k získání umístění prostředku v libovolném systému souborů.
Někteří klienti musí mít za každou cenu lokální reprezentaci souboru. Mohou například s tímto souborem spouštět nativní nástroj nebo používat knihovny, které nevědí o Eclipse, jenž dokážou ošetřit pouze prostředky systému souborů (jako např. java.util.zip.ZipFile). V takovýchto případech můžete požádat IFileStore o návrat lokální kopie svého obsahu uložené do mezipaměti:
IFileStore store = ...;//nějaké uložení souboru //zjistěte, zda může být přímo reprezentován jako lokální soubor java.io.File local = store.toLocalFile(EFS.NONE, null); //pokud ne, vyžádejte si lokální kopii souboru uloženou do mezipaměti if (local == null) local = store.toLocalFile(EFS.CACHE, null);
Uvědomte si, že jakmile je získána kopie souboru uložená do mezipaměti, nezůstává synchronizována se skutečným systémem souborů, odkud pochází. Úprava kopie uložené do mezipaměti nezpůsobí úpravu základního souboru.
Klienti, kteří nedokážou ošetřit prostředky mimo lokální systém souborů, mohou i nadále chtít adaptovat svůj kód na postupnější selhání. Klienti mohou zkontrolovat, zda se prostředek nachází v lokálním systému souborů, a buď jej ignorovat, anebo varovat uživatele v případě, že narazí na prostředek, který nedokážou ošetřit. Chcete-li určit, zda se prostředek nachází v lokálním systému souborů, musíte vyhledat jeho schéma systému souborů. To můžete získat od prostředku takto:
IResource resource = ...;//některý prostředek URI uri = resource.getLocationURI(); if (uri != null && EFS.SCHEME_LOCAL.equals(uri.getScheme())) { //soubor je v lokálním systému souborů } else { //soubor není v lokálním systému souborů }
Máte-li připravenu instanci IFileStore, můžete získat schéma takto:
IFileStore store = ...;//úložiště souborů store.getFileSystem().getScheme();
Co je ovlivněno: Klienti, kteří volají MultiPageEditorSite.progressStart()
nebo MultiPageEditorSite.progressEnd()
.
Popis: Během vývoje Eclipse 3.0 byly přidány tyto metody jako součást podpory indikace průběhu. Před verzí 3.0 došlo ke změně způsobu ošetřování průběhu a tato metoda již nebyla zapotřebí. Díky chybě programátora byly tyto veřejné metody ve verzi 3.0 ponechány. Tyto dvě metody neposkytovaly ve verzi Eclipse nikdy žádnou funkci, a proto byly odstraněny.
Nezbytná akce: Klienti volající
MultiPageEditorSite.progressStart()
nebo
MultiPageEditorSite.progressEnd()
by měli místo toho přepnout na
IWorkbenchSiteProgressService
.
Co je ovlivněno: Klienti, kteří mají vlastní config.ini a přesouvají svoji aplikaci do verze 3.2.
Popis: Před verzí 3.2 byla typická hodnota pro osgi.bundles obsažená v config.ini org.eclipse.core.runtime@2:start, org.eclipse.update.configurator@3:start
.
Kvůli opětovné deklaraci běhové komponenty musí být tato hodnota aktualizována, aby se aplikace úspěšně spustila.
Nezbytná akce:Změňte hodnotu osgi.bundles na vkládané soubory org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start,
org.eclipse.core.runtime@start.
Co je ovlivněno: Klienti implementující aplikace RCP, kteří určili hodnotu pro osgi.bundles.
Popis: Před verzí 3.2 byla typická hodnota pro osgi.bundles obsažená v hlavním souboru jnlp org.eclipse.core.runtime@2:start, org.eclipse.update.configurator@3:start
.
Kvůli opětovné deklaraci běhové komponenty musí být tato hodnota aktualizována, jinak by došlo k NullPointerException
a k zabránění spuštění aplikace.
Nezbytná akce:Změňte hodnotu osgi.bundles na vkládané soubory org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start,
org.eclipse.core.runtime@start.
Co je ovlivněno: Klienti, kteří volají Bundle.start()
.
Popis:
V Eclipse se balík pro pomalé spuštění zadává pomocí záhlaví Eclipse-LazyStart
(nebo nepřípustného záhlaví Eclipse-AutoStart
). V Eclipse 3.1 metoda org.osgi.framework.Bundle.start()
neoznačovala balíky pro pomalé spuštění jako trvale spuštěné. Protože balíky pro pomalé spuštění nikdy nebyly označeny jako trvale spuštěné, nemohly být automaticky spuštěny při restartování Eclipse. Dokumentace Javadoc pro Bundle.start()
uvádí, že při volání metody musí nastat následující podmínky:
"Záznam o trvalém spuštění tohoto balíku. Jakmile je restartován rámec Framework, musí být tento balík automaticky spuštěn."
V Eclipse 3.2 byla metoda Bundle.start()
opravena tak, aby řádně označila
balík jako trvale spuštěný, i když jde o balík pro pomalé spuštění. Tato oprava byla
nezbytná, aby byly splněny specifikace OSGi Framework. V důsledku toho si volající
Bundle.start()
vynutí spuštění balíku při restartování Eclipse.
Toto je obecně považováno za nesprávný postup, protože to způsobuje aktivaci nepotřebných
balíků při každém spuštění Eclipse. V některých případech může dojít k neočekávaným výsledkům, jako např. chyba 134412.
Nezbytná akce: Klienti Bundle.start()
musí vyhodnotit,
zda je trvalá aktivace balíku po každém restartování v jejich zájmu. Pokud ne, klienti
by měli najít jiný způsob aktivace balíku. Ve většině případů se lze volání
Bundle.start()
jednoduše vyhnout povolením pomalé aktivace cílového balíku
při načítání tříd z tohoto balíku. Existují výjimečné scénáře, které vyžadují
agresivní aktivaci balíku pro pomalé spuštění, ale ne jeho trvalé označení pro aktivaci při restartování. Tyto typy scénářů by měly místo volání Bundle.start()
používat Bundle.loadClass()
k načtení třídy z balíku, který musí být aktivován.
V Eclipse 3.0 nebylo použití znaku podtržítka ('_') v segmentu kvalifikátoru identifikátoru verze podporováno, ale ani vynucováno. Pokud identifikátor verze modulu plug-in obsahoval v kvalifikátoru podtržítko,
byl tento znak při exportu modulu plug-in do systému souborů a také při instalaci modulu plug-in z webu s aktualizacemi převeden na pomlčku ('-').
V Eclipse 3.1 byla zvolněna pravidla pro povolené znaky v kvalifikátorech tak, aby zahrnovaly znak podtržítka, takže když byl vadný modul plug-in exportován nebo instalován, nebyl kvalifikátor oproti původnímu stavu upraven.
Tato jemná změna byla v příručce pro migraci z verze 3.0 na verzi 3.1 vynechána.
Příběh (ve verzi Eclipse 3.2) pokračuje tak, že dodržujeme kompatibilitu s Eclipse 3.1. Moduly plug-in používající znaky podtržítka ve svých kvalifikátorech verzí by si při zacházení se starými verzemi modulů plug-in (při exportu a pokud existují na webu s aktualizacemi) měly být vědomy výše uvedených změn. To například znamená, že poskytovatelé modulů plug-in, kteří mají na svém webu s aktualizacemi staré verze modulů plug-in, by se měli ujistit, zda název v systému souborů odpovídá názvu modulu plug-in.