O Eclipse mudou relativamente à incompatibilidade entre o 3.1 e o 3.2 de formas que afectam os plug-ins. As entradas seguintes descrevem as áreas que foram alteradas e facultam instruções para migrar os plug-ins 3.1 para 3.2. Repare que apenas necessita de consultar estas entradas se está a detectar problemas na execução do plug-in 3.1 no 3.2.
O que é afectado:Os clientes da API IWorkspace
que presumem que os recursos estão armazenados no sistema de ficheiros local.
Descrição: Nas versões anteriores ao Eclipse 3.2, cada
IResource
existente tinha um ficheiro correspondente ou um
directório num sistema de ficheiros acessível através do java.io.File
.
No Eclipse 3.2, foi adicionado suporte para criar recursos cujos conteúdos estão
armazenados num sistema de ficheiros de apoio arbitrários.
Os recursos que utilizem este suporte já não podem ser representados
directamente como sendo um java.io.File.
Acção requerida: O método antigo IResource.getLocation() devolve o sistema de ficheiros local de um recurso. Este método devolve nulo para recursos que não estejam armazenados no sistema de ficheiros local. A maioria dos chamadores do getLocation() fazem-no de modo a obter uma instância do java.io.File, que já não possa ser utilizada para os recursos que não estão armazenados no sistema de ficheiros local.
O novo plug-in org.eclipse.core.filesystem faculta uma API de sistema de ficheiros genérica que pode ser utilizada em vez de java.io.File. Especialmente, uma instância do org.eclipse.core.filesystem.IFileStore faculta a maioria dos mesmos métodos que estão disponíveis no java.io.File. O fragmento seguinte de código obtém uma instância do IFileStore de um determinado recurso:
IResource resource = ...;//some resource IFileStore store = EFS.getStore(resource.getLocationURI());
A tabela seguinte faculta métodos equivalentes no IFileStore para operações que são geralmente efectuadas com o java.io.File:
java.io.File | IFileStore |
---|---|
eliminar | eliminar |
getName | getName |
getParent | getParent |
list | childNames |
mkdir | mkdir(EFS.SHALLOW, null) |
mkdirs | mkdir(EFS.NONE, null) |
renameTo | mover |
new FileInputStream(file) | openInputStream |
new FileOutputStream(file) | openOutputStream |
Na API IFileStore, a maior parte da informação sobre um ficheiro é armazenada numa estrutura denominada IFileInfo, obtida ao chamar o IFileStore.fetchInfo(). Esta concepção permite uma maior optimização do código que utiliza o java.io.File, uma vez que uma grande parte dos atributos de um ficheiro podem ser obtidos através de uma única chamada de sistema de ficheiros. Repare que a informação contida num IFileInfo tornar-se-á obsoleta se o ficheiro subjacente for alterado e, por conseguinte, as instâncias só deverão ser mantidas enquanto forem necessárias. Seguem-se alguns métodos contidos no java.io.File que são métodos equivalentes no 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) |
Como exemplo concreto, o código que anteriormente chamava java.io.File.exists() pode agora chamar IFileStore.fetchInfo().exists(). Quando um IFileInfo é modificado, é necessário armazenar o resultado através da utilização do método IFileStore.putInfo. Por exemplo, este fragmento inverte o atributo só de leitura num ficheiro
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);
Assim como o método getLocation(), a localização da descrição do projecto pode já não se encontrar no sistema de ficheiros local. O método IProjectDescription.getLocationURI() pode ser utilizado para obter a localização de um recurso num sistema de ficheiro arbitrário.
Alguns clientes têm mesmo de ter uma representação local de um ficheiro. Por exemplo, podem estar a lançar uma ferramenta nativa em relação a esse ficheiro ou a utilizar bibliotecas que não estejam conscientes do Eclipse e que apenas consigam processar recursos de sistemas de ficheiros (tal como java.util.zip.ZipFile). Nestes casos, pode requerer que um IFileStore devolva uma cópia local colocada na memória cache dos seus conteúdos:
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);
Repare que quando uma cópia de um ficheiro colocada na memória cache é obtida, esta não se mantém em sincronia com o sistema de ficheiros do qual adveio. A modificação da cópia colocada na memória cache não levará à modificação do ficheiro subjacente.
Os clientes que não possam processar recursos fora do sistema de ficheiros local, podem querer adaptar o seu código para que falhe graciosamente. Os clientes podem verificar se um recurso se encontra no sistema de ficheiros local e podem ignorar o recurso ou alertar o utilizador quando encontrarem um recurso que não conseguem processar. Para determinar se um recurso se encontra no sistema de ficheiros local, é necessário encontrar o esquema do sistema de ficheiros. Este esquema pode ser obtido a partir de um recurso da seguinte forma:
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 }
Se tiver a instância IFileStore em questão, pode obter o esquema da seguinte forma:
IFileStore store = ...;//a file store store.getFileSystem().getScheme();
O que é afectado: Os clientes que chamam o MultiPageEditorSite.progressStart()
or
MultiPageEditorSite.progressEnd()
.
Descrição: Durante o desenvolvimento do Eclipse 3.0, estes métodos foram adicionados como parte do trabalho de suporte de progresso. Antes da edição da versão 3.0, foi alterada a forma de processar o progresso e este método tornou-se desnecessário. Através de erros do programador, estes métodos públicos foram deixados para a edição da versão 3.0. Estes dois métodos nunca serviram nenhuma função numa edição do Eclipse e, por conseguinte, foram eliminados.
Action required: Clients calling
MultiPageEditorSite.progressStart()
or
MultiPageEditorSite.progressEnd()
should switch to using
IWorkbenchSiteProgressService
instead.
O que é afectado: Os clientes que contêm um config.ini personalizado e que deslocam a aplicação para a versão 3.2.
Descrição: Nas versões anteriores à 3.2, o valor comum dos
osgi.bundles contidos no config.ini era org.eclipse.core.runtime@2:start,
org.eclipse.update.configurator@3:start
.
Devido à refactorização do tempo de
execução, este valor necessita de ser actualizado para que a actualização
inicie com sucesso.
Acção requerida:Alterar o valor de osgi.bundles para
incluir org.eclipse.equinox.common@2:start,
org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start.
O que é afectado: Os clientes que implementam aplicações RCP e que especificam um valor para osgi.bundles.
Descrição: Nas versões anteriores à 3.2, o valor comum dos
osgi.bundles contidos no ficheiro jnlp principal era
org.eclipse.core.runtime@2:start,
org.eclipse.update.configurator@3:start
.
Devido à refactorização do tempo de
execução, este valor necessita de ser actualizado, caso contrário as
NullPointerException
poderiam ser lançadas, evitando que a
aplicação fosse iniciada.
Acção requerida:Alterar o valor de osgi.bundles para
incluir org.eclipse.equinox.common@2:start,
org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start.
O que é afectado: Os clientes que chamam o Bundle.start()
.
Descrição: No Eclipse, um agrupamento é especificado para
ser um agrupamento de início lento através da utilização do cabeçalho
Eclipse-LazyStart
(ou do cabeçalho obsoleto Eclipse-AutoStart
).
No Eclipse 3.1, o método org.osgi.framework.Bundle.start()
não
marcou os agrupamentos de início lento como sendo iniciados
persistentemente. Uma vez que os
agrupamentos de início lento nunca foram marcados como sendo
iniciados persistentemente, estes não serão automaticamente iniciados aquando
do reinício do eclipse. O javadoc para
Bundle.start()
declara que deverá ocorrer o seguinte, quando o método é chamado:
"Registe persistentemente que este agrupamento foi iniciado. Quando o Enquadramento for reinicidado, este agrupamento tem de ser iniciado automaticamente."
No Eclipse 3.2, o método Bundle.start()
foi corrigido de modo a
marcar adequadamente o agrupamento como sendo iniciado persistentemente, mesmo
que o agrupamento seja de início lento.
Esta correcção tinha de estar em conformidade com especificação do Enquadramento OSGi.
Por conseguinte, os chamadores de Bundle.start()
irão obrigar o
agrupamento a ser iniciado quando o Eclipse for reiniciado.Geralmente, esta
acção é considerada como sendo um mau procedimento, uma vez que fará com que
agrupamentos desnecessários sejam activados de cada vez que o Eclipse é iniciado.
Em alguns casos, poderá provocar resultados inesperados, tais como
bug 134412.
Acção requerida: Os clientes de Bundle.start()
necessitam de avaliar se a intenção é activar persistentemente o agrupamento em cada reinício.
Caso não seja essa a intenção, os clientes deverão encontrar uma outra forma de
activar o agrupamento. Na maioria dos casos, as chamadas
Bundle.start()
podem ser evitadas simplesmente ao permitir que o
agrupamento de destino seja activado lentamente quando as classe forem carregadas
a partir delas. Existem situações raras que requerem que um agrupamento de
início lento seja activado agressivamente, mas que não seja marcado
persistentemente para activação num reinício. Estes tipos de situações deverão utilizar
Bundle.loadClass()
para carregar uma classe para o agrupamento que
necessita de ser activado, em vez de chamar Bundle.start()
.
No Eclipse 3.0, a utilização de um carácter de traço de sublinhado ("_") no
segmento do qualificador do identificador de versão não era suportada, mas
também não era executada. Se um identificador de versão de plug-in contivesse
um carácter de traço de sublinhado no qualificador, este carácter era
transformado em hífen ("-") ao exportar o plug-in para o sistema de ficheiros e
também ao instalar o plug-in a partir de um sítio de actualização.
No Eclipse 3.1, as regras para caracteres aceites pelos qualificadores
permitiam a inclusão do carácter de traço de sublinhado, para que quando um
plug-in infractor fosse exportado ou instalado, o estado original do qualificador não
fosse alterado. Esta alteração subtil foi acidentalmente excluída do manual de
migração das versões 3.0 e 3.1.
Sucede-se que (para o Eclipse 3.2) foi mantida a compatibilidade entre o
Eclipse 3.1 e os plug-ins que utilizam caracteres de traço de sublinhado nos
respectivos qualificadores de versões, deverão ter em conta as alterações
supramencionadas ao trabalhar com versões antigas de plug-ins (ao exportá-las e
quando estas existem em sítios de actualização). Isto significa, por exemplo,
que os fornecedores de plug-ins que contenham versões antigas de plug-ins num
sítio de actualização deverão certificar-se que o nome no sistema de ficheiros
corresponde ao nome do plug-in.