Niezgodności między wersjami 3.1 i 3.2 środowiska Eclipse

W wersji 3.2 środowiska Eclipse wprowadzono zmiany powodujące niezgodność z wersją 3.1, które mają wpływ na wtyczki. Poniżej opisano obszary, w których nastąpiły zmiany, a także podano instrukcje umożliwiające migrację wtyczek z wersji 3.1 do wersji 3.2. Z podanych informacji należy korzystać jedynie w sytuacji, gdy przy uruchamianiu wtyczki z wersji 3.1 w środowisku w wersji 3.2 występują problemy.

  1. Zniesienie wymogu umieszczania zasobów w lokalnym systemie plików
  2. Zmiany w interfejsie API klasy MultiPageEditorSite
  3. Zmiany w treści pliku config.ini
  4. Zmiany w treści wdrożonych aplikacji jnlp
  5. Wymuszanie aktywacji pakunku przy kolejnym restarcie przez jawne wywołania metody Bundle.start()
  6. Wyeliminowanie zastępowania znaku podkreślenia łącznikiem w numerach wersji wtyczek

1. Zniesienie wymogu umieszczania zasobów w lokalnym systemie plików

Zakres: Klienty interfejsu API IWorkspace, w przypadku których zakłada się, że zasoby są przechowywane w lokalnym systemie plików.

Opis: Przed wprowadzeniem wersji 3.2 środowiska Eclipse wszystkim istniejącym interfejsom IResource odpowiadały pliki lub katalogi w systemie plików, które były dostępne za pośrednictwem klasy java.io.File. W środowisku Eclipse 3.2 dodano możliwość tworzenia zasobów, których treść jest przechowywana w dowolnym systemie plików. Zasoby korzystające z tej opcji nie mogą już być odzwierciedlane bezpośrednio jako klasa java.io.File.

Wymagane działanie: Dotychczasowa metoda IResource.getLocation() zwraca ścieżkę do zasobu w lokalnym systemie plików. W przypadku zasobów, które nie są przechowywane w lokalnym systemie plików, zwracana jest wartość zerowa. W większości elementów wywołujących metodę getLocation() rozwiązanie to było stosowane w celu uzyskania instancji klasy java.io.File, której nie można już stosować w odniesieniu do zasobów przechowywanych poza lokalnym systemem plików.

Nowa wtyczka org.eclipse.core.filesystem pozwala uzyskać dostęp do ogólnego interfejsu API systemu plików, z którego można korzystać zamiast klasy java.io.File. Instancja interfejsu org.eclipse.core.filesystem.IFileStore pozwala korzystać z większości metod dostępnych za pośrednictwem klasy java.io.File. Poniższy fragment kodu pozwala uzyskać instancję interfejsu IFileStore w odniesieniu do danego zasobu:

   IResource resource = ...;//zasób
   IFileStore store = EFS.getStore(resource.getLocationURI());

W poniższej tabeli przedstawiono metody interfejsu IFileStore odpowiadające operacjom wykonywanym zazwyczaj za pomocą klasy java.io.File.

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

W przypadku interfejsu API IFileStore większość informacji o pliku jest przechowywana w strukturze pod nazwą IFileInfo, którą uzyskuje się poprzez wywołanie metody IFileStore.fetchInfo(). Rozwiązanie to pozwala lepiej zoptymalizować kod niż klasa java.io.File, ponieważ wiele atrybutów związanych z plikiem można w wielu przypadkach uzyskać za pomocą jednego wywołania do systemu plików. Informacje zawarte w interfejsie IFileInfo stają się nieaktualne w przypadku zmiany pliku, którego dotyczą. W związku z tym instancje należy przechowywać wyłącznie wtedy, gdy są potrzebne. Poniżej przedstawiono metody klasy java.io.File, które mają swoje odpowiedniki w interfejsie IFileInfo:

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

Konkretnym przykładem może być kod, za pomocą którego wcześniej wywoływano metodę java.io.File.exists(), a obecnie można wywołać metodę IFileStore.fetchInfo().exists(). Zmodyfikowanie interfejsu IFileInfo powoduje konieczność ponownego zapisania rezultatów za pomocą metody IFileStore.putInfo. Poniższy fragment kodu służy do zmiany atrybutu "tylko do odczytu" pliku.

   IFileStore store = ...;//składnica plików
   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()

Podobnie jak w przypadku metody getLocation(), opis projektu nie musi znajdować się w lokalnym systemie plików. Metoda IProjectDescription.getLocationURI() pozwala uzyskać informację o położeniu zasobu w dowolnym systemie plików.

Buforowanie lokalne

W przypadku niektórych klientów konieczne jest lokalne odwzorowanie pliku. Dzieje się tak na przykład w sytuacji, w której uruchamiane jest rodzime narzędzie odwołujące się do danego pliku lub wykorzystywane są biblioteki nierozpoznające środowiska Eclipse, umożliwiające wyłącznie obsługę zasobów znajdujących się w systemie plików (np. java.util.zip.ZipFile). W takich przypadkach interfejs IFileStore zwraca na żądanie lokalną kopię treści zasobu przechowywaną w buforze.

   IFileStore store = ...;//składnica plików
   //Sprawdzenie, czy plik można odwzorować bezpośrednio jako plik lokalny
   java.io.File local = store.toLocalFile(EFS.NONE, null);
   //Jeśli nie, żądanie udostępnienia lokalnej kopii pliku
   if (local == null)
      local = store.toLocalFile(EFS.CACHE, null);

Kopia pliku uzyskana z bufora nie pozostaje zsynchronizowana z wersją znajdującą się w systemie plików, z którego pochodzi. Zmodyfikowanie kopii przechowywanej w buforze nie powoduje zmodyfikowania pliku bazowego.

Kontrolowana obsługa błędów

Kod klientów, które nie obsługują zasobów znajdujących się poza lokalnym systemem plików, można modyfikować w taki sposób, aby ich działanie w przypadku błędów było bardziej kontrolowane. Klienty mogą sprawdzać, czy dany zasób znajduje się w lokalnym systemie plików, a następnie ignorować je bądź powiadamiać użytkownika o napotkaniu nieobsługiwanego zasobu. Aby stwierdzić, czy zasób znajduje się w lokalnym systemie plików, należy poznać schemat systemu plików tego zasobu. Schemat ten można uzyskać z zasobu w następujący sposób:

   IResource resource = ...;//zasób
   URI uri = resource.getLocationURI();
   if (uri != null && EFS.SCHEME_LOCAL.equals(uri.getScheme())) {
      //Plik znajduje się w lokalnym systemie plików
   } else {
      //Plik nie znajduje się w lokalnym systemie plików
   }

Jeśli dostępna jest instancja interfejsu IFileStore, schemat można uzyskać w następujący sposób:

   IFileStore store = ...;//składnica plików
   store.getFileSystem().getScheme();

2. Zmiany w interfejsie API klasy MultiPageEditorSite

Zakres: Klienty wywołujące metodę MultiPageEditorSite.progressStart() lub MultiPageEditorSite.progressEnd().

Opis: Podczas opracowywania wersji 3.0 środowiska Eclipse dodano powyższe metody, które mają na celu zapewnienie obsługi informacji o postępie. Przed wprowadzeniem wersji 3.0 sposób obsługi informacji o postępie uległ zmianie, w związku z czym ówczesna metoda przestała być potrzebna. W wyniku błędu programistów powyższe metody publiczne pozostały jednak w wersji 3.0. Nie spełniały one jednak żadnej funkcji w którejkolwiek wersji środowiska Eclipse, w związku z czym zostały usunięte.

Wymagane działanie: Klienty wywołujące metodę MultiPageEditorSite.progressStart() lub MultiPageEditorSite.progressEnd() należy przełączyć na korzystanie z interfejsu IWorkbenchSiteProgressService.

3. Zmiany w treści pliku config.ini

Zakres: Klienty korzystające z niestandardowych plików config.ini, których aplikacje są przenoszone do wersji 3.2.

Opis: Przed wprowadzeniem wersji 3.2 atrybut osgi.bundles w pliku config.ini miał standardowo wartość org.eclipse.core.runtime@2:start, org.eclipse.update.configurator@3:start. W związku z refaktoryzacją środowiska wykonawczego wartość tę należy zaktualizować, aby można było pomyślnie uruchomić aplikację.

Wymagane działanie: Należy zmienić wartość atrybutu osgi.bundles na następującą: org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start.

4. Zmiany w treści wdrożonych aplikacji jnlp

Zakres: Klienty, na których wdrożono aplikacje RCP i określono wartość atrybutu osgi.bundles.

Opis: Przed wprowadzeniem wersji 3.2 atrybut osgi.bundles w głównym pliku jnlp miał standardowo wartość org.eclipse.core.runtime@2:start, org.eclipse.update.configurator@3:start. W związku z refaktoryzacją środowiska wykonawczego wartość tę należy zaktualizować. W przeciwnym razie mogą być zgłaszane błędy NullPointerException, które uniemożliwiają uruchomienie aplikacji.

Wymagane działanie: Należy zmienić wartość atrybutu osgi.bundles na następującą: org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start.

5. Wymuszanie aktywacji pakunku przy kolejnym restarcie przez jawne wywołania metody Bundle.start()

Zakres: Klienty wywołujące metodę Bundle.start().

Opis: W środowisku Eclipse opóźnione uruchamianie pakunku określa się za pomocą nagłówka Eclipse-LazyStart (lub nieaktualnego nagłówka Eclipse-AutoStart). W wersji Eclipse 3.1 skorzystanie z metody org.osgi.framework.Bundle.start() nie powodowało oznaczenia pakunków uruchamianych z opóźnieniem jako uruchamianych trwale. W związku z tym pakunki uruchamiane z opóźnieniem nie były nigdy oznaczane jako uruchamiane trwale, a tym samym nie były automatycznie uruchamiane przy restarcie środowiska Eclipse. W dokumentacji Javadoc dotyczącej metody Bundle.start() wskazano, że przy wywoływaniu metody:

"Należy trwale zarejestrować, że pakunek został uruchomiony. Przy restarcie środowiska pakunek musi zostać uruchomiony automatycznie."

W środowisku Eclipse 3.2 metoda Bundle.start() została skorygowana w sposób umożliwiający prawidłowe oznaczanie pakunku jako uruchamianego trwale, nawet jeśli jest to pakunek uruchamiany z opóźnieniem. Poprawka ta była niezbędna w celu zapewnienia zgodności ze specyfikacją środowiska OSGi. W rezultacie elementy wywołujące metodę Bundle.start() będą wymuszały uruchamianie pakunku w przypadku restartu środowiska Eclipse. Zasadniczo działanie takie uznaje się za niewłaściwe, ponieważ powoduje ono aktywowanie zbędnych pakunków przy każdym uruchomieniu środowiska Eclipse. W niektórych przypadkach może to powodować nieoczekiwane rezultaty, takie jak w przypadku błędu 134412.

Wymagane działanie: W przypadku klientów korzystających z metody Bundle.start() należy ocenić, czy pakunek ma być z założenia aktywowany trwale przy każdym restarcie. Jeśli nie jest to zamierzone działanie, należy określić inny sposób uruchamiania pakunku przez klienta. W większości przypadków można uniknąć wywołań metody Bundle.start(), umożliwiając opóźnioną aktywację pakunku docelowego z chwilą ładowania zawartych w nim klas. Są to dosyć nietypowe sytuacje, w których wymaga się szybkiej aktywacji pakunku uruchamianego z opóźnieniem, nie ma natomiast potrzeby trwałego oznaczania tego pakunku jako aktywowanego po restarcie. W takich sytuacjach zamiast wywoływać metodę Bundle.start() należy skorzystać z metody Bundle.loadClass(), aby załadować klasę z pakunku, który ma zostać aktywowany.

5. Wyeliminowanie zastępowania znaku podkreślenia łącznikiem w numerach wersji wtyczek

W środowisku Eclipse 3.0 korzystanie ze znaku podkreślenia ("_") w segmencie kwalifikatora identyfikatora wersji nie było obsługiwane ani egzekwowane. Jeśli kwalifikator identyfikatora wersji wtyczki zawierał znak podkreślenia, podczas eksportowania wtyczki do systemu plików oraz instalowania wtyczki z serwisu z aktualizacjami znak ten był przekształcany w łącznik ("-").
W środowisku Eclipse 3.1 reguły dotyczące dozwolonych znaków w kwalifikatorach zostały rozluźnione, co pozwoliło uwzględnić znak podkreślenia. W związku z tym podczas eksportu lub instalacji wtyczki, której nazwa zawiera taki znak, kwalifikator nie ulega zmianie. Zmiana ta została przypadkowo pominięta w podręczniku migracji z wersji 3.0 do wersji 3.1.W późniejszych wersjach (także w wersji Eclipse 3.2) zachowywana jest zgodność z wersją Eclipse 3.1. W związku z tym w przypadku wspomnianych wcześniej wtyczek, których kwalifikatory wersji zawierają znaki podkreślenia, należy uwzględnić powyższe zmiany, ponieważ mają one wpływ na obsługę wcześniejszych wersji tych wtyczek (zarówno przy eksporcie, jak i przy pobieraniu z witryn z aktualizacjami). Oznacza to na przykład, że dostawcy wtyczek dysponujący wcześniejszymi wersjami wtyczek w serwisie z aktualizacjami powinni dopilnować, aby nazwy w systemie plików odpowiadały faktycznym nazwom wtyczek.