Entre las versiones 3.1 y 3.2, Eclipse ha cambiado de forma que presenta incompatibilidades que afectan a los plug-ins. Los siguientes puntos describen las áreas que han cambiado y suministran instrucciones para migrar plug-ins de la versión 3.1 a la versión 3.2. Tenga en cuenta que sólo necesita consultarlos si experimenta problemas al ejecutar el plug-in 3.1 en 3.2.
Elementos afectados: los clientes de la API IWorkspace
que presuponen que los recursos
están almacenados en el sistema de archivos local.
Descripción: antes de Eclipse 3.2, cada IResource
existente tenía un archivo o un
directorio correspondiente en un sistema de archivos al que podía acceder java.io.File
. En Eclipse 3.2 se
añadió soporte para crear recursos cuyos contenidos se almacenan en un sistema de archivos de respaldo
arbitrario. Los recursos que utilizan este soporte ya no pueden representarse directamente como un
java.io.File.
Acción necesaria: el antiguo método IResource.getLocation() devuelve la vía de acceso del sistema de archivos local de un recurso. Este método devuelve nulo para los recursos que no se han almacenado en el sistema de archivos local. La mayoría de llamadores de getLocation() lo hacían así para obtener una instancia de java.io.File que ya no puede utilizarse para recursos que no están almacenados en el sistema de archivos local.
El plug-in org.eclipse.core.filesystem nuevo proporciona una API del sistema de archivos genérico que puede utilizarse en lugar de java.io.File. En concreto, una instancia de org.eclipse.core.filesystem.IFileStore proporciona la mayoría de los mismos métodos que están disponibles en java.io.File. El fragmento de código siguiente obtiene una instancia de IFileStore para un recurso dado:
IResource resource = ...;//algún recurso IFileStore store = EFS.getStore(resource.getLocationURI());
La tabla siguiente proporciona métodos equivalente en IFileStore para operaciones que normalmente se realizan con 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 |
En la API IFileStore, la mayoría de la información acerca de un archivo se almacena en una estructura llamada IFileInfo que se obtiene llamando a IFileStore.fetchInfo(). Este diseño permite obtener una mayor optimización del código utilizando java.io.File, porque muchos atributos de un archivo pueden obtenerse a menudo con una sola llamada de sistema de archivos. Tenga en cuenta que la información de un IFileInfo se volverá obsoleta si el archivo subyacente se cambia por lo que las instancias solo deben mantenerse mientras sean necesarias. A continuación se proporcionan algunos métodos de java.io.File que tienen métodos equivalentes en 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) |
A modo de ejemplo, el código que antes llamaba a java.io.File.exists(), ahora puede llamar a IFileStore.fetchInfo().exists(). Cuando se modifica IFileInfo, el resultado debe volver a almacenarse utilizando el método IFileStore.putInfo. Por ejemplo, este fragmento de código invierte el atributo de solo lectura en un archivo
IFileStore store = ...;//un almacén de archivos 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);
Como en el método getLocation(), la ubicación de la descripción del proyecto ya no estará en el sistema de archivos local. El método IProjectDescription.getLocationURI() puede utilizarse para obtener la ubicación de un recurso en un sistema de archivos arbitrario.
Algunos clientes deben tener necesariamente una representación local de un archivo. Por ejemplo, pueden estar lanzando una herramienta nativa contra ese archivo o utilizando bibliotecas desconocidas para Eclipse que solo puedan manejar recursos del sistema de archivos (como por ejemplo java.util.zip.ZipFile). En estos casos, puede pedir un IFileStore para devolver una copia local en memoria caché del contenido:
IFileStore store = ...;//un almacén de archivos //ver si puede representarse directamente como archivo local java.io.File local = store.toLocalFile(EFS.NONE, null); //si no, preguntar por una copia local del archivo en memoria caché if (local == null) local = store.toLocalFile(EFS.CACHE, null);
Tenga en cuenta que una vez se obtiene una copia en memoria caché de un archivo, no permanece en sincronía con el sistema de archivos local del que provenía. Al modificar la copia en memoria caché no se modificará el archivo subyacente.
Los clientes que no pueden manejar recursos fuera del sistema de archivos local querrán adaptar su código para que la anomalía sea más elegante. Los clientes pueden comprobar si un recurso está en el sistema de archivos local e ignorar el recurso o alertar al usuario cuando encuentran un recurso que no pueden manejar. Para determinar si un recurso está en el sistema de archivos local, necesita descubrir su esquema de sistema de archivos. Puede obtener esto a partir de un recurso de la manera siguiente:
IResource resource = ...;//algún recurso URI uri = resource.getLocationURI(); if (uri != null && EFS.SCHEME_LOCAL.equals(uri.getScheme())) { //el archivo está en el sistema de archivos local } else { //el archivo no está en el sistema de archivos local }
Si tiene a mano una instancia IFileStore, puede obtener el esquema de la manera siguiente:
IFileStore store = ...;//un almacén de archivos store.getFileSystem().getScheme();
Elementos afectados: los clientes que llaman a MultiPageEditorSite.progressStart()
MultiPageEditorSite.progressEnd()
.
Descripción: durante el desarrollo de Eclipse 3.0, estos métodos se añadieron como parte del trabajo de soporte del progreso. Antes del release 3.0, la forma en que se manejaba el progreso cambió y este método ya no resultaba necesario. Por error del programador, estos métodos públicos quedaron en el release 3.0. Estos dos métodos nunca han dado servicio a ninguna función en un release de Eclipse y por lo tanto se han suprimido.
Acción necesaria: los clientes que llaman a MultiPageEditorSite.progressStart()
o
MultiPageEditorSite.progressEnd()
deben pasar a utilizar IWorkbenchSiteProgressService
en su
lugar.
Elementos afectados: los clientes que tienen un archivo config.ini personalizado y migran sus aplicaciones a 3.2.
Descripción: antes de 3.2, el valor habitual para osgi.bundles
contenido en el archivo config.ini era org.eclipse.core.runtime@2:start,
org.eclipse.update.configurator@3:start
.
Debido a la refactorización del entorno de
ejecución, este valor debe actualizarse para que la aplicación se inicie
satisfactoriamente.
Acción necesaria: cambie el valor de osgi.bundles para que incluya org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start,
org.eclipse.core.runtime@start.
Elementos afectados: los clientes que despliegan aplicaciones RCP y han especificado un valor para osgi.bundles.
Descripción: antes de 3.2, el valor habitual para osgi.bundles
contenido en el archivo jnlp principal era
org.eclipse.core.runtime@2:start, org.eclipse.update.configurator@3:start
.
Debido a la refactorización del entorno de
ejecución, este valor debe actualizarse; de lo contrario, se lanzarán excepciones de
tipo NullPointerException
que impedirán el inicio de la aplicación.
Acción necesaria: cambie el valor de osgi.bundles para que incluya
org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start,
org.eclipse.core.runtime@start.
Elementos afectados: los clientes que llaman a Bundle.start()
.
Descripción:
en Eclipse, un paquete compuesto se especifica como paquete compuesto de inicio
poco activo mediante la cabecera Eclipse-LazyStart
(o la cabecera obsoleta
Eclipse-AutoStart
). En Eclipse 3.1, el método
org.osgi.framework.Bundle.start()
no marcaba los paquetes compuestos de
inicio poco activo como iniciados de forma persistente. Dado que los paquetes compuestos
de inicio poco activo nunca se marcaban como iniciados de forma persistente, no se iniciaban
automáticamente cuando se reiniciaba Elipse. El
javadoc de Bundle.start()
indica que debe producirse lo siguiente cuando
se llama al método:
"Registrar de forma persistente que este paquete compuesto se ha iniciado. Cuando se reinicie la infraestructura, este paquete compuesto debe iniciarse automáticamente."
En Eclipse 3.2 el método Bundle.start()
se ha modificado para marcar
adecuadamente el paquete compuesto como iniciado de forma persistente aunque sea un
paquete compuesto de inicio poco activo. Este arreglo debía ajustarse a la especificación de
la infraestructura OSGi. Como resultado, los llamadores de Bundle.start()
forzarán el inicio del paquete compuesto cuando se reinicie Eclipse. En general esto se
considera un mal procedimiento, ya que provocará la activación de paquetes compuestos
innecesarios cada vez que se inicie Eclipse. En algunos casos puede provocar resultados
inesperados, como por ejemplo el
error 134412.
Acción necesaria: los clientes de Bundle.start()
deben evaluar si su propósito es activar de forma persistente el paquete compuesto en
todos los reinicios. Si no es así, los clientes deben encontrar otra forma de activar el
paquete compuesto. En la mayoría de los casos, las llamadas a Bundle.start()
pueden evitarse permitiendo simplemente que el paquete compuesto destino se active en
modalidad diferida cuando se cargan las clases desde él. En raras ocasiones, puede ser
necesaria una activación agresiva de un paquete compuesto de inicio poco activo, pero sin
marcarlo persistentemente para activación durante el reinicio. En estos casos, debe
utilizarse Bundle.loadClass()
para cargar una clase del paquete compuesto
que debe activarse, en lugar de llamar a Bundle.start()
.
En Eclipse 3.0, el uso de un carácter de subrayado ('_') en el segmento calificador de
un identificador de versión no estaba soportado, pero tampoco se aplicaba. Si un
identificador de versión de plug-in contenía un subrayado en el calificador, este
carácter se transformaba en un guión ('-') al exportar el plug-in al sistema de archivos
y también al instalar el plug-in desde un sitio de actualizaciones.
En Eclipse 3.1, las normas de los caracteres permitidos en los calificadores se relajaron
para incluir el carácter de subrayado, de forma que cuando se exportara o instalara un
plug-in especificado incorrectamente, el calificador no se modificara con respecto a su
estado original.
Este pequeño cambio se omitió accidentalmente de la guía de migración de 3.0 a 3.1.
La continuación de la historia es que (para Eclipse 3.2) se mantiene la compatibilidad
con Eclipse 3.1 y los plug-ins que utilicen caracteres de subrayado en sus calificadores
de versión deben tener en cuenta los cambios mencionados anteriormente al tratar con
versiones antiguas de plug-in (tanto al exportar como si existen en sitios de
actualizaciones). Esto significa, por ejemplo, que los proveedores de plug-ins que tengan
versiones antiguas de su plug-in en un sitio de actualizaciones deben asegurarse de que
el nombre que figura en el sistema de archivos coincide con el nombre que figura en el
plug-in.