Изменения между Eclipse версий 2.1 и 3.0 повлекли за собой некоторые несовместимости, касающиеся модулей. Ниже приведено описание измененных областей и инструкции для переноса модулей версии 2.1 в 3.0. Обратите внимание, что этот раздел будет полезен только при наличии трудностей при переносе модуля 2.1 в версию 3.0.
Заголовок файлов манифестов для модулей (и фрагментов модулей) изменился и включает в себя новую строку, идентифицирующую версию манифеста соответствующего модуля. До версии 3.0 модули не имели строк <?eclipse ...?>, с выходом версии 3.0, они должны иметь такую строку. Это изменение позволяет Eclipse различать модули до версии 3.0, которые не были импортированы в 3.0, чтобы они смогли предоставить более надежную двоичную совместимость для таких модулей. Ниже приведен пример общей формы файла plugin.xml (fragment.xml схож с ним):
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin ...>
...
</plugin>
Созданные PDE 3.0 манифесты модулей автоматически имеют такую форму. Настоятельно рекомендуется использовать утилиту миграции PDE. Она автоматически вставляет указанную строку в манифест модулей 2.1 и фрагменты модулей и вносит многие другие изменения, отмеченные в этом разделе.
Если вы добавили эту директиву к plugin.xml (вручную или с помощью PDE), следует обновить файл и явно указать список модулей, с которыми он связан. Например, до выпуска Eclipse 3.0, зависимости от org.eclipse.core.runtime и org.eclipse.core.boot были неявными. В версии 3.0 org.eclipse.core.boot больше не нужен, и разработчики должны выбрать либо org.eclipse.core.runtime, или org.eclipse.core.runtime.compatibility (или ни один из них).
Примечание: Эта несовместимость не влияет на выполнение двоичных модулей 2.1 в Eclipse 3.0.
Модуль org.eclipse.ui, который раньше был главным модулем пользовательского интерфейса платформы, теперь предоставляет только API и точки расширения для общей (то есть не специфической для IDE) рабочей среды. Необязательный и специфический для IDE API, а также точки расширения были перемещены в другие модули.
В результате произошли следующие изменения: (1) перемещенные точки расширения org.eclipse.ui имеют новые ИД точек расширения; и (2) изменился список обязательных модулей.
Точки расширения org.eclipse.ui в следующей таблице были перемещены в другие модули, что привело к изменению их ИД точек расширения. Если имеющийся модуль добавит расширение к перемещенной точке расширения, следует изменить ссылку в атрибуте "point" элемента <extension> в файле манифеста модуля, чтобы он отражал новые ИД соответствующих точек расширения. Утилита миграции PDE самостоятельно внесет эти исправления за вас.
Примечание: Эта несовместимость не влияет на выполнение двоичных модулей 2.1 в Eclipse 3.0. Eclipse 3.0 автоматически обнаруживает модули версии ранее 3.0 (за счет отсутствия упомянутой выше строки <?eclipse version="3.0"?> в манифесте модуля) и автоматически обрабатывает эти изменения точки расширения и зависимости модуля.
Старый ИД точки расширения |
Новый ИД точки расширения |
org.eclipse.ui.markerHelp | org.eclipse.ui.ide.markerHelp |
org.eclipse.ui.markerImageProviders | org.eclipse.ui.ide.markerImageProviders |
org.eclipse.ui.markerResolution | org.eclipse.ui.ide.markerResolution |
org.eclipse.ui.projectNatureImages | org.eclipse.ui.ide.projectNatureImages |
org.eclipse.ui.resourceFilters | org.eclipse.ui.ide.resourceFilters |
org.eclipse.ui.markerUpdaters | org.eclipse.ui.editors.markerUpdaters |
org.eclipse.ui.documentProviders | org.eclipse.ui.editors.documentProviders |
org.eclipse.ui.workbench.texteditor. markerAnnotationSpecification |
org.eclipse.ui.editors.markerAnnotationSpecification |
В следующей таблице приведен список пакетов API, ранее предоставляемых модулем org.eclipse.ui, перемещенных в другие модули. (Имена пакетов API, классов, полей и методов не изменились). В некоторых случаях пакеты API теперь разделены между несколькими модулями. Так как классы API, видимые модулям, определяются списком обязательных модулей модуля, эти изменения могут потребовать настройки элементов "<requires>" манифеста имеющихся модулей, чтобы сохранить доступ к классам API.
Эти изменения требуются только для модулей, зависящих от модуля org.eclipse.ui (который включает <import plugin="org.eclipse.ui"/> в разделе <requires> манифеста модуля); к другим модулям это не относится. Если это затрагивает другие модули, может потребоваться изменить элемент <import> или добавить дополнительные элементы <import>, чтобы все классы API, требуемые для вашего модуля, находились внутри одной области. Настоятельно рекомендуется, чтобы модули указывали только зависимости на те модули, которые они действительно используют. Указание ненужных зависимостей снижает быстродействие, так как загрузчик классов Java вынужден искать классы во всех связанных модулях. (Утилита миграции PDE исправит все зависимости и поможет определить их минимальный набор).
Пакет API |
Модуль 2.1 |
Соответствующие модули 3.0 |
org.eclipse.jface.text.* | org.eclipse.ui | org.eclipse.jface.text |
org.eclipse.text.* | org.eclipse.ui | org.eclipse.jface.text |
org.eclipse.ui | org.eclipse.ui | org.eclipse.ui, org.eclipse.ui.ide |
org.eclipse.ui.actions | org.eclipse.ui | org.eclipse.ui, org.eclipse.ui.ide |
org.eclipse.ui.dialogs | org.eclipse.ui | org.eclipse.ui, org.eclipse.ui.ide |
org.eclipse.ui.editors.* | org.eclipse.ui | org.eclipse.ui.editor |
org.eclipse.ui.model | org.eclipse.ui | org.eclipse.ui, org.eclipse.ui.ide |
org.eclipse.ui.part | org.eclipse.ui | org.eclipse.ui, org.eclipse.ui.ide |
org.eclipse.ui.texteditor | org.eclipse.ui | org.eclipse.ui.workbench.texteditor, org.eclipse.ui.editors |
org.eclipse.ui.texteditor.* | org.eclipse.ui | org.eclipse.ui.workbench.texteditor |
org.eclipse.ui.views.bookmarkexplorer | org.eclipse.ui | org.eclipse.ui.ide |
org.eclipse.ui.views.contentoutline | org.eclipse.ui | org.eclipse.ui.views |
org.eclipse.ui.views.markers | org.eclipse.ui | org.eclipse.ui.ide |
org.eclipse.ui.views.navigator | org.eclipse.ui | org.eclipse.ui.ide |
org.eclipse.ui.views.properties | org.eclipse.ui | org.eclipse.ui.views |
org.eclipse.ui.views.tasklist | org.eclipse.ui | org.eclipse.ui.ide |
org.eclipse.ui.wizards.datatransfer | org.eclipse.ui | org.eclipse.ui.ide |
org.eclipse.ui.wizards.newresource | org.eclipse.ui | org.eclipse.ui.ide |
Выполнение платформы Eclipse 3.0 основано на OSGi, из-за чего в структуру двух модулей выполнения платформы потребовалось внести изменения - в org.eclipse.core.runtime и org.eclipse.core.boot.
Новый модуль org.eclipse.core.runtime.compatibility предоставляет связку между новыми и старыми API, он также является хранилищем многих устаревших API, ранее находившихся в org.eclipse.core.runtime и org.eclipse.core.boot. Эта реструктуризация не затронула точки расширения выполнения платформы.
При миграции имеющегося модуля в 3.0 манифест модуля следует обновить, чтобы он отражал новую структуру модулей выполнения платформы Eclipse. Утилита миграции PDE самостоятельно добавит необходимые зависимости в org.eclipse.core.runtime.compatibility.
Также обратите внимание на то, что если пометить модуль как относящийся к версии 3.0 (с помощью <?eclipse version="3.0"?>), и модуль задает класс Plugin, следует явно указать <import plugin="org.eclipse.core.runtime.compatibility"/> в манифесте модуля, чтобы класс Plugin определял конструктор по умолчанию.
Примечание: Эта несовместимость не влияет на выполнение двоичных модулей 2.1 в Eclipse 3.0. Eclipse 3.0 автоматически обнаруживает модули версии ранее 3.0 (за счет отсутствия упомянутой выше строки <?eclipse version="3.0"?> в манифесте модуля) и автоматически обрабатывает эти изменения во время выполнения.
Модуль org.eclipse.xerces был удален за ненадобностью. Поддержка обработки XML теперь встроена в J2SE 1.4, и присутствие модуля Xerces создает конфликты загрузчиков классов. Пакеты API javax.xml.parsers, org.w3c.dom.* и org.xml.sax.*, ранее предоставляемые модулем org.eclipse.xerces, теперь доступны в библиотеках J2SE.
Если модулю требуется модуль org.eclipse.xerces, следует изменить манифест модуля и удалить эту зависимость. После этого следует скомпилировать код модуля, и можно будет его выполнять.
Двоичные модули 2.1 с указанной зависимостью на модуль org.eclipse.xerces не будут удовлетворять предварительным требованиям при запуске в стандартной конфигурации Eclipse 3.0. Как результат, модуль не сможет быть активирован.
До выпуска версии 3.0 в Eclipse в основном работала одна нить. Большинство методов API и точек расширения выполнялись или в нити пользовательского интерфейса, или в нити, ответвленной от окна состояния, блокировавшего нить пользовательского интерфейса. При создании модулей в большинстве случаев не стоило волноваться о безопасности нитей, следовало лишь убедиться, что все действия пользовательского интерфейса выполнялись в нити пользовательского интерфейса. В Eclipse 3.0 в целом параллельность выполнения выше. Теперь многие операции выполняются в фоновой нити, где они могут работать одновременно с другими нитями, включая нить пользовательского интерфейса. Все модули, код которых выполняется в фоновой нити, должны обеспечивать безопасность нитей своего кода.
Кроме модулей, явно выполняющих свои операции в фоновом режиме с помощью API org.eclipse.core.runtime.jobs
, есть несколько средств API платформы и точек расширения, использующих фоновые нити. Модули, относящиеся к этим средствам, должны обеспечить безопасность кода для нитей. В следующей таблице приведены API и точки расширения, выполняющие частично или полностью свой код в фоновой нити Eclipse 3.0:
Точка расширения или класс API |
Примечания |
org.eclipse.core.runtime.IRegistryChangeListener | Новый в Eclipse 3.0, работает в фоновом режиме |
org.eclipse.core.resources.IResourceChangeListener | События AUTO_BUILD теперь выполняются в фоновом режиме |
org.eclipse.core.resources.builders (ext. point) | Автоматическая компоновка теперь выполняется в фоновом режиме |
org.eclipse.core.resources.ISaveParticipant | SNAPSHOT теперь выполняется в фоновом режиме |
org.eclipse.ui.workbench.texteditor.quickdiffReferenceProvider (ext. point) | Новый в Eclipse 3.0, работает в фоновом режиме |
org.eclipse.ui.decorators (ext. point) | Уже работал в фоновом режиме в Eclipse 2.1 |
org.eclipse.ui.startup (ext. point) | Уже работал в фоновом режиме в Eclipse 2.1 |
org.eclipse.team.core.org.eclipse.team.core.repository (ext. point) | Многие операции теперь выполняются в фоновом режиме |
org.eclipse.team.ui.synchronizeParticipants (ext. point) | Новый в Eclipse 3.0, работает в фоновом режиме |
org.eclipse.debug.core.launchConfigurationTypes (ext. point) | Теперь выполняется в фоновом режиме |
org.eclipse.jdt.core.IElementChangedListener | ElementChangedEvent.PRE_AUTO_BUILD теперь выполняется в фоновом режиме; POST_RECONCILE уже работал в фоновом режиме |
Для повышения безопасности кода для нитей есть несколько приемов. Самое простое решение - убедиться, что вся работа происходит в нити пользовательского интерфейса, обеспечив таким образом последовательное выполнение задач. Это довольно распространенный подход для модулей пользовательского интерфейса, не слишком загружающих CPU. При таком подходе будьте готовы к риску возникновения тупика в Display.syncExec
. Использовать Display.asyncExec
обычно более безопасно, так как нет риска возникновения тупика, но при этом теряется полный контроль за выполнением кода.
Другие методы повышения безопасности кода для нитей включают в себя:
org.eclipse.core.runtime.jobs.ILock
.
Преимущество ILock
перед другими способами блокировки заключается в том, что они могут автоматически переходить к нити пользовательского интерфейса syncExec
, и в поддержке обнаружения тупиков, записывающей в протокол и устраняющей тупики. Display.asyncExec
), выполняемую полностью в нити пользовательского интерфейса. java.lang.String
и org.eclipse.core.runtime.IPath
. Преимуществом неизменяемых объектов является чрезвычайно быстрый доступ для чтения за счет необходимости выполнять дополнительные действия при модификации. Следующие методы были удалены из интерфейса org.eclipse.ui.IWorkbenchPage. IWorkbenchPage объявляется в общей рабочей среде, но его методы - специфические для ресурсов.
Клиенты этих методов IWorkbenchPage.openEditor должны вместо этого вызывать соответствующие открытые статические методы, объявленные в классе org.eclipse.ui.ide.IDE (в модуле org.eclipse.ui.ide).
Клиенты этого метода IWorkbenchPage.openSystemEditor(IFile) должны преобразовать IFile в IEditorInput с помощью нового FileEditorInput(IFile) и затем вызвать метод openEditor(IEditorInput,String). Иными словами, переписать page.openSystemEditor(file) в виде page.openEditor(new FileEditorInput(file), IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID). Примечание: клиенты, использующие ИД редактора IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID должны передать ввод редактора, реализующий org.eclipse.ui.IPathEditorInput (что делает FileEditorInput).
Примечание: Эта несовместимость не влияет на выполнение двоичных модулей 2.1 в Eclipse 3.0. Eclipse 3.0 включает в себя механизм двоичной совместимости, обеспечивающий работу имеющихся двоичных модулей 2.1, использующих любые удаленные методы openEditor и openSystemEditor, как в версии 2.1, несмотря на изменения API. (Удаленные методы по сути "добавляются обратно" фрагментом org.eclipse.ui.workbench.compatibility).Следующий метод был удален из интерфейса org.eclipse.ui.IEditorPart. IEditorPart объявляется в общей рабочей среде, но его методы - специфические для ресурсов.
Вызывающие этот методы клиенты должны вместо этого убедиться, что компонент редактора реализует или принимает org.eclipse.ui.ide.IGotoMarker (в модуле org.eclipse.ui.ide), и если это так, вызвать gotoMarker(IMarker). У класса IDE есть удобный способ сделать это: IDE.gotoMarker(редактор, маркер);
Клиенты, реализующие редактор, который может разместиться, опираясь на информацию IMarker, должны реализовывать или принимать org.eclipse.ui.ide.IGotoMarker.Так как единственным методом IGotoMarker является gotoMarker(IMarker), он имеет одинаковые сигнатуру и спецификацию со старым IEditorPart.gotoMarker(IMarker), реализация имеющегося редактора может принять это изменение, просто включив IGotoMarker в оператор implements определения класса.
В двоичных модулях 2.1 с кодом, вызывающим этот метод, возникнет исключительная ситуация ошибки связывания классов при запуске в стандартной конфигурации 3.0.
Интерфейс запуска редактора org.eclipse.ui.IEditorLauncher реализуется модулями, дополняющими внешние редакторы. Следующий метод был удален из этого интерфейса. IEditorLauncher объявляется в общей рабочей среде, но его методы - специфические для ресурсов.
Был заменен на
В двоичных модулях 2.1 с кодом, вызывающим этот метод, возникнет исключительная ситуация ошибки связывания классов при запуске в стандартной конфигурации 3.0.
Следующие методы были удалены из интерфейса org.eclipse.ui.IEditorRegistry. IEditorRegistry объявляется в общей рабочей среде, но его методы - специфические для ресурсов.
Теперь есть новые константы, представляющие идентификаторы системного внешнего редактора и системного встроенного редактора (SYSTEM_EXTERNAL_EDITOR_ID и SYSTEM_INPLACE_EDITOR_ID). Для этих двух редакторов обязателен ввод редактора, реализующий или принимающий org.eclipse.ui.IPathEditorInput. Обратите внимание, что дескриптор встроенного редактора не будет присутствовать в конфигурации Eclipse, не поддерживающей встроенное редактирование.
Следующий метод был удален из интерфейса org.eclipse.ui.IWorkbench. IWorkbench объявляется в общей рабочей среде, но его методы - специфические для ресурсов.
В двоичных модулях 2.1 с кодом, вызывающим этот метод, возникнет исключительная ситуация при запуске в стандартной конфигурации 3.0.
Для того чтобы сделать org.eclipse.ui.texteditor.AbstractTextEditor независимым от IFile, org.eclipse.ui.texteditor.AbstractDocumentProvider предоставляет концепцию операции провайдера документа (DocumentProviderOperation) и исполнителя операции провайдера документа (IRunnableContext). По запросу на сброс, сохранение или синхронизацию AbstractDocumentProvider создает операции провайдера документа и использует исполнителя операций для их выполнения. Исполняемый контекст может быть предоставлен производными классами с помощью метода getOperationRunner. Ниже приведены сведения об изменениях, которые должен принимать клиент:
Производный класс AbstractDocumentProvider - org.eclipse.ui.editors.text.StorageDocumentProvider - реализует метод getOperationRunner для возврата нулевого значения. Это означает, что производные классы StorageDocumentProvider не должны быть затронуты данным изменением.
org.eclipse.ui.editors.text.FileDocumentProvider, производный класс StorageDocumentProvider, реализует метод getOperationRunner, возвращающий IRunnableContext для выполнения операций DocumentProviderOperations внутри WorkspaceModifyOperation. Среди других изменений FileDocumentProvider можно отметить:
Изменения в org.eclipse.ui.texteditor.AbstractTextEditor:
ResourceAction action= new AddMarkerAction(TextEditorMessages.getResourceBundle(), "Editor.AddBookmark.", this, IMarker.BOOKMARK, true); //$NON-NLS-1$ action.setHelpContextId(ITextEditorHelpContextIds.BOOKMARK_ACTION); action.setActionDefinitionId(ITextEditorActionDefinitionIds.ADD_BOOKMARK); setAction(IDEActionFactory.BOOKMARK.getId(), action);
action= new AddTaskAction(TextEditorMessages.getResourceBundle(), "Editor.AddTask.", this); //$NON-NLS-1$ action.setHelpContextId(ITextEditorHelpContextIds.ADD_TASK_ACTION); action.setActionDefinitionId(ITextEditorActionDefinitionIds.ADD_TASK); setAction(IDEActionFactory.ADD_TASK.getId(), action);
Производный класс AbstractTextEditor - org.eclipse.ui.texteditor.StatusTextEditor предоставляет предикатный метод isErrorStatus(IStatus). Производные классы могут переопределять его для того, чтобы решить, следует ли расценивать заданное состояние как ошибку или нет.
Изменения в org.eclipse.ui.text.AbstractDecoratedTextEditor:
В Annotation были внесены следующие изменения в ходе внедрения поддержки комментариев без заголовков:
org.eclipse.jface.text.source.Annotation org.eclipse.jface.text.source.AnnotationModel org.eclipse.jface.text.source.AnnotationModelEvent org.eclipse.jface.text.source.IAnnotationModel org.eclipse.jface.text.source.IAnnotationModelListener org.eclipse.jface.text.source.IAnnotationModelListenerExtension
В Eclipse 3.0 поддерживается консоль. Консоль доступна с помощью меню Окно > Показать панель > Основные > Консоль и используется отладчиком Eclipse и для интеграции Ant.
ИД панели для консоли изменился с org.eclipse.debug.ui.ConsoleView на org.eclipse.ui.console.ConsoleView. Модули 2.1, программно открывающие консоль, вызовут ошибку, так как эта старая панель больше не существует.
В версии 3.0 типы возврата методов org.eclipse.jdt.debug.core.IJavaBreakpointListener.breakpointHit(IJavaBreakpoint, IJavaThread) и installingBreakpoing(IJavaTarget, IJavaBreakpoint, IJavaType) изменились с boolean на int чтобы позволить получателям запросов откликаться "безразлично". В предшествующих 3.0 версиях получатели запросов могли откликаться только как "приостановить" или "не приостанавливать" при попадания в точку прерывания, либо "установить" или "не устанавливать" перед установкой точки прерывания. В версии 3.0 получатели запросов могут также откликаться "безразлично" на любое из этих событий. Это позволяет клиентам делать выбор только в небезразличных им ситуациях. Для уведомлений о "попаданиях в точку прерывания", точка прерывания приостанавливается, если получатель запроса откликнулся "приостановить" или все получатели запросов откликнулись "безразлично"; либо, точка прерывания не будет приостановлена, если хотя бы один получатель запроса откликнулся "не приостанавливать" и ни один из получателей запроса не откликнулся "приостановить". Точно также, для уведомлений об "установке точки прерывания" точка прерывания будет установлена, если один или несколько получателей запросов откликнулись "установить" или все получатели запросов откликнулись "безразлично"; и она не будет установлена, если хотя бы один получатель запросов откликнулся как "не устанавливать" и ни один из получателей не откликнулся "установить". В целом, должно возвращаться значение DONT_CARE (безразлично) если нет точной уверенности в других вариантах. Обратите внимание, что, например, отклик "приостановить" переопределит отклики "не приостанавливать" других получателей запросов.
Интерфейс IJavaBreakpointListener реализуется клиентами, создающими или реагирующими на точки прерывания кода Java. Есть мало клиентов помимо JDT, за исключением того, который исправляет ошибку (bug 37760). Это существенное изменение имеющегося кода, реализующего интерфейс IJavaBreakpointListener. Этот код требуется изменить, чтобы он возвращал допустимое целое значение (int) перед его компиляцией или выполнением в версии 3.0.
До выпуска версии 3.0 методы в SWT-классе org.eclipse.swt.dnd.Clipboard могли негласно выполняться не только в нити пользовательского интерфейса. Это приводило к сбоям GTK, где операционная система требует выполнения всех операций с буфером обмена в нити пользовательского интерфейса. Ранее это оставалось незамеченным, так как многие приложения используют всего одну нить и по большей части тестируются в Windows. Чтобы API буфера обмена оставался стабильным и работал на всех платформах, в версии 3.0 были изменены спецификации и реализации всех методов API буфера обмена и теперь выдают сообщение об исключительной ситуации SWT (ERROR_THREAD_INVALID_ACCESS) при вызове не из нити пользовательского интерфейса. Службы буфера обмена обычно автоматически предоставляются такими компонентами Eclipse, как текстовый редактор, что изолирует многих клиентов от этого изменения. Следует убедиться, что имеющийся код, напрямую использующий буфер обмена, вызывает методы API в правильной нити, используя Display.asyncExec или syncExec для смещения доступа к нити пользовательского интерфейса.
В версии 3.0 SWT сообщает о нажатиях клавиш до того, как событие будет обработано в операционной системе. Это гораздо раньше, чем в предыдущих версиях. Данное изменение было сделано для поддержки привязок клавиш в Eclipse, требующей перехвата нажатий клавиш до того, как другой управляющий элемент обработал символ. Последствия этого изменения видны коду, обрабатывающему напрямую низкоуровневые события org.eclipse.swt.SWT.KeyDown. Например, это означает, что когда получатель запросов управляющего элемента Text получает событие нажатия клавиши, содержимое элемента (getText()) не будет включать в себя нажатую клавишу (как это было в версиях до 3.0). Рекомендованным способом получить полный текст из управляющего элемента, включая текущую нажатую клавишу, является обработка событий высокого уровня SWT.Modify or SWT.Verify, а не события низкого уровня SWT.KeyDown; такой код не затронут данным изменением.
До выпуска версии 3.0, когда активным был класс SWT org.eclipse.swt.widgets.Canvas или один из его производных классов (включая пользовательские управляющие элементы), нажатие Ctrl+Tab, Shift+Tab, Ctrl+PgUp или Ctrl+PgDn приводило к автоматическому переходу к следующему/предыдущему управляющему элементу, и событие нажатия клавиши не обрабатывалось. Это поведение было произвольным и выполнялось вопреки правилу о том, что Canvas должен обрабатывать все нажатые клавиши. Правильным способом обработки переходов является регистрация получателя запросов переходов. Для правильной поддержки привязок клавиш в Eclipse 3.0 поведение по умолчанию было изменено, чтобы Canvas распознавал нажатия клавиш Ctrl+Tab, Shift+Tab, Ctrl+PgUp и Ctrl+PgDn вместо простого перехода. Если вы используете сам Canvas или задаете производный класс для Canvas, не забудьте зарегистрировать получатель запросов перехода.
При выборе с помощью мыши элементов в классах SWT org.eclipse.swt.widgets.Table и Tree создается последовательность событий MouseDown-Selection-MouseUp во всех операционных средах. Точно так же выбор с помощью клавиатуры создает последовательность событий KeyDown-Selection-KeyUp одинаково во всех операционных средах. До версии 3.0 порядок событий не был унифицирован, в Motif и Photon всегда вначале шло событие Selection, то есть - Selection-MouseDown-MouseUp или Selection-KeyDown-KeyUp. В 3.0 порядок событий для Motif и Photon был изменен и стал таким же, как везде. Имеющийся код, корректно функционирующий в {Windows, GTK} и {Motif, Photon}, вряд ли будет затронут этим изменением. Тем не менее, рекомендуется проверить код и убедиться, что он не использует неверный порядок событий.
org.eclipse.core.runtime.IStatus
обладает новой константой серьезности IStatus.CANCEL
, которую можно использовать для указания отмены. Это нововведение затронет вызывающие IStatus.getSeverity()
элементы, полагающие, что набор возможных серьезностей ограничен IStatus.OK
,
INFO
, WARNING
и ERROR
. Вызывающие getSeverity
элементы должны обновить свой код и добавить в него новую серьезность.
В Eclipse 3.0 автоматическая компоновка рабочей области теперь происходит в фоновой нити. Это требует изменения контракта API на org.eclipse.core.resources.IResourceChangeEvent
. Контракт IResourceChangeEvent
ранее гарантировал следующий порядок событий для всех изменений рабочей области:
PRE_DELETE
или PRE_CLOSE
, если это допустимоPRE_AUTO_BUILD
POST_AUTO_BUILD
POST_AUTO_CHANGE
Так как теперь автоматическая компоновка выполняется в фоновом режиме, невозможно гарантировать временные отношения между событиями AUTO_BUILD
и событием POST_CHANGE
. В Eclipse 3.0 шаги 3-5 описанной выше последовательности удалены. В результате это выглядит так:
PRE_DELETE
или PRE_CLOSE
, если это допустимоPOST_AUTO_CHANGE
Периодически платформа будет выполнять компоновку рабочей области в фоновом режиме. Обратите внимание, что это происходит, несмотря на включение или выключение автоматической компоновки. Точное время выполнения компоновки не указывается. Структура операции компоновки будет выглядеть так:
PRE_BUILD
(PRE_BUILD
является новым именем для PRE_AUTO_BUILD)
POST_BUILD
(POST_BUILD
является новым именем для POST_AUTO_BUILD)
POST_AUTO_CHANGE
Точка отсчета для дельт, получаемых получателями запросов автоматической компоновки, будет отличаться от получателей запросов post-change. Получатели запросов компоновки будут получать уведомления обо всех изменениях, произведенных с конца последней операции компоновки. Получатели запросов post-change будут получать дельты, описывающие все изменения после последнего уведомления post-change. Эта новая структура сохраняет три характеристики получателей запросов изменений ресурсов, действительные начиная с Eclipse 1.0:
POST_CHANGE
получают уведомления о всех изменениях ресурсов, произошедших за время их регистрации. Сюда относятся изменения, сделанные компоновщиками и другими получателями запросов. PRE_AUTO_BUILD
получают уведомления о всех изменениях ресурсов, за исключением изменений, сделанных компоновщиками и получателями запросов изменений ресурсов. POST_AUTO_BUILD
получают уведомления о всех изменениях ресурсов, за исключением изменений, сделанных другими получателями запросов POST_AUTO_BUILD
.
Тем не менее, в таком подходе есть и некоторые отличия. До выпуска Eclipse 3.0 получатели запросов автоматической компоновки всегда вызывались перед получателями запросов POST_CHANGE
. По этой причине дельта, получаемая получателями запросов автоматической компоновки всегда являлась лишь подмножеством дельты, получаемой получателями запросов POST_CHANGE
.
Теперь эта взаимосвязь обращена. Получатели запросов автоматической компоновки теперь получают дельту, являющуюся надмножеством всех дельт, отправляемых получателю запросов POST_CHANGE
после окончания последней компоновки в фоновом режиме. Как и раньше, получатели запросов автоматической компоновки смогут изменять рабочую область, а получателям запросов post-change это запрещено.
Больше после завершения операции внесения изменений в рабочую область получатели запросов событий AUTO_BUILD
не будут уведомляться. Клиентский код, регистрирующий получателей запросов изменений ресурсов с помощью IWorkspace.addResourceChangeListener(IResourceChangeListener)
, вряд ли будет затронут этим изменением, так как события AUTO_BUILD
никогда не сообщались этим получателям запросов. Однако, клиенты, использующие IWorkspace.addResourceChangeListener(IResourceChangeListener,int)
и задают шаблон событий, включающий в себя события AUTO_BUILD
, могут пострадать от этого изменения, если они будут делать предположения о том, когда выполняются получатели запросов автоматической компоновки или в какой нити они выполняются. Например, если получатель запросов обновляет модель домена, чтобы она отражала изменения в рабочей области, это обновление может и не произойти, когда заканчивается операция изменения рабочей области. Следует отметить, что таким образом может быть затронут только код уровня пользовательского интерфейса. Код уровня ядра, вызываемый через API, может быть вызван внутри области IWorkspaceRunnable
, поэтому нет никаких гарантий,
когда будут вызваны получатели запросов изменений ресурсов. Для исправления этой ошибки можно использовать POST_CHANGE
вместо получателей запросов компоновки, если требуется получение уведомлений перед завершением операции.
Больше не гарантируется, что все изменения ресурсов, происходящие во время выполнения динамической области IWorkspaceRunnable
, будут объединены в одном уведомлении. Такой механизм все же можно использовать для группировки изменений ради избежания ненужных компоновок и уведомлений, но теперь платформа может решать, выполнять ли уведомления во время операции. Изменение контракта API скорее всего не повлияет на работу имеющихся клиентов. Это равнозначно решению платформы периодически вызывать IWorkspace.checkpoint
во время продолжительной операции. Благодаря этому изменению теперь несколько нитей могут изменять рабочую область одновременно. Когда одна нить заканчивает изменение рабочей области, требуется уведомление, чтобы предотвратить неполадки отклика системы, даже если другая операция еще не была завершена. Это изменение также позволяет пользователям приступить к работе с набором ресурсов прежде, чем завершится операция. Например, пользователь может просматривать файлы проекта, который еще проверяется. Новый метод IWorkspace.run(IWorkspaceRunnable,
ISchedulingRule, int, IProgressMonitor)
содержит необязательный флаг AVOID_UPDATE
, который могут использовать операции для подсказки платформе, нужны ли периодические обновления.
Затронутые компоненты: модули, добавляющие расширения к точке расширения org.eclipse.core.runtime.urlHandlers
.
Описание: Контракт точки расширения org.eclipse.core.runtime.urlHandlers
был изменен для использования службы обработки потока URL, предоставляемой OSGi. Поддержка OSGi превосходит Eclipse 2.1, и она корректно управляет динамическими обработчиками. Из-за некоторых моментов, связанных с механизмом обработки Java URL, URLStreamHandlers, зарегистрированный в службе обработки OSGi, должен применять org.osgi.service.url.URLStreamHandlerService
.
Необходимое действие: ранее класс обработки должен был реализовывать java.net.URLStreamHandler
и расширять точку расширения urlHandlers. Эта точка расширения больше не поддерживается, и обработчик должен применять интерфейс org.osgi.service.url.URLStreamHandlerService
. Система OSGi предоставляет абстрактный базовый класс (org.osgi.service.url.AbstractURLStreamHandlerService
) который может быть использован как производный класс для этой роли.
Вместо регистрации обработчика с помощью точки расширения модули теперь должны регистрировать обработчики как службы. Пример:
Hashtable properties = new Hashtable(1); properties.put(URLConstants.URL_HANDLER_PROTOCOL, new String[] {MyHandler.PROTOCOL}); String serviceClass = URLStreamHandlerService.class.getName(); context.registerService(serviceClass, new MyHandler(), properties);
Затронутые компоненты: модули, предоставляющие пакеты, которые также предоставлены другими модулями. Лишь немногие модули затрагиваются этим изменением, и некоторые из них от нее только выиграют.
Описание: В Eclipse 2.x загрузчики классов ищут классы в следующем порядке: (1) родительский загрузчик класса (обычно это загрузчик загрузочного Java класса), (2) содержимое собственных classpath и (3) все предварительные требования в объявленном порядке. OSGi позволяет оптимизировать эту модель. В предлагаемом подходе загрузчик класса проверяет (1) родительский загрузчик класса (скорее всего, это загрузчик загрузочного Java класса), затем либо (2a) отдельное предварительное требование, дополняющее классы, или (2b) собственные записи путей классов на наличие требуемых классов.
Загрузчик классов определяет, следует ли проверять себя или свои предварительные требования, основываясь на импортированных и обязательных пакетах. Эта информация берется из содержимого модуля в случае традиционных модулей или указывается непосредственно в случае модулей с явным манифестом обработки OSGi. В любом случае известно априори, какие загрузчики классов предоставляют классы для каких пакетов. Это позволяет повысить производительность и предлагает решение неприятной проблемы множества предварительных требований, дополняющих одинаковые классы.
Например в случае с Xerces и Xalan, они оба содержат различные классы из пакетов org.xml. Используя первый метод, модуль Xerces увидит свои копии этих классов, а модуль Xalan будет видеть свои копии этих классов. Так как эти модули должны взаимодействовать, возникает ClassCastExceptions. Используя второй подход, только один из двух модулей вносит дополнения из дублирующихся классов, и оба модуля видят одинаковые копии.
Обязательное действие: требуемое действие зависит от особенностей каждого случая. Разработчикам следует пересмотреть classpath и устранить все возможные конфликты.
Затронутые компоненты: модули, ожидающие, что домен защиты их загрузчика классов постоянно присутствует.
Описание: в Eclipse 2.1 загрузчики классов модулей относились к java.security.SecureClassloaders и всегда имели домен защиты. В Eclipse 3.0 загрузчики классов не расширяют SecureClassloader, а только задают домен защиты если безопасность Java включена (что обычно не так).
Обязательное действие: требуемое действие зависит от сценария, в котором модуль использует домен защиты.
Затронутые компоненты: модули, которые преобразуют объекты или типы org.eclipse.core.runtime.IPlugin* в org.eclipse.core.runtime.model.Plugin*Model. Даже несмотря на то, что взаимосвязь между этими интерфейсами и классами модели не указана в API Eclipse 2.1, мы явно называем это изменением, так как обнаружили экземпляры модулей, ссылающиеся на эту взаимосвязь в реализации 2.1.
Описание: Eclipse API предоставляет несколько интерфейсов (например, IPluginDescriptor
) и так называемых классов "моделей" (например, PluginDescriptorModel
), связанных с модулями и реестрами модулей. В реализации Eclipse 2.1 случалось, что классы модели реализовали соответствующие интерфейсы. В новой версии на базе OSGi реестр модулей был значительно переработан, чтобы разделять аспекты загрузки классов и предварительных требований модулей и аспекты расширений и точек расширений. Eclipse 3.0 не может динамически поддерживать реализацию этой взаимосвязи, представленную в 2.1.
Обязательные действия: следует переработать код модулей, зависящих от этой не документированной в API взаимосвязи. Дополнительные сведения по этому вопросу приведены в разделе рекомендуемых изменений данного документа и в Javadoc для связанных классов и методов.
Затронутые компоненты: модули, использующие org.eclipse.core.runtime.ILibrary
.
Описание: при новом динамическом подключении записи classpath хранятся другим, не совместимым с Eclipse способом. В результате уровень совместимости не в состоянии правильно смоделировать основные структуры OSGi как объекты ILibrary. Поддержка динамической совместимости создает объекты ILibrary, но должна допускать значения по умолчанию для всех элементов кроме пути библиотеки.
Обязательное действие: пользователям ILibrary рекомендуется обращаться к требуемым значениям обработчиков (то есть Bundle-Classpath
) из соответствующего Bundle (см. Bundle.getHeaders()
), используя вспомогательный класс ManifestElement
для обработки этих записей. Дополнительные сведения приведены в классе Javadoc.
Затронутые компоненты: модули, делающие предположения об своей структуре установки, размещении и разметке локальной файловой системы.
Описание: методы, такие как IPluginDescriptor.getInstallURL()
, возвращают URL определенной формы. Несмотря на то, что их формы являются произвольными, различные модули делают предположения, основываясь на текущей реализации. Например, они могут ожидать URL типа file:
и использовать URL.getFile() и вследствие этого java.io.File
. До недавнего времени этот подход работал, но ненадежно. Например, если модуль установлен на Web-сервере, будет скорее всего возвращен http:
URL. Гибкость Eclipse 3.0 во время выполнения открывает большие возможности для выполнения конфигураций (то есть, сохраняя все модули в файлах JAR, а не в различных каталогах). Таким образом, хотя OSGi и не нарушает работу 2.1 API, возрастает число ситуаций, когда подобные предположения становятся недопустимыми.
Обязательные действия: авторы модулей должны убедиться в том, что нужная им информация доступна через getResource()
(и находится в classpath), или должны использовать API для доступа к содержимому модуля (то есть Bundle.getEntry(String)
).
Затронутые компоненты: не относящийся к модулям код, вызывающий определенные методы из класса org.eclipse.core.boot.BootLoader
.
Описание: статические методы BootLoader.startup(), shutdown() и run() были перемещены в org.eclipse.core.runtime.adaptor.EclipseStarter, являющийся частью структуры OSGi. Этот API является интерфейсом между main() в startup.jar и динамическим подключением OSGi структуры/Eclipse. После реструктуризации системы эти методы невозможно было оставить в BootLoader. Старый класс BootLoader теперь расположен в уровне динамической совместимости и считается устаревшим, перемещенные методы не работают.
Замены для старого BootLoader.getRunnable() нет, так как захват отдельных приложений более не поддерживается. Вместо этого пользователям следует указывать интересующие их приложения при запуске платформы.
Обязательные действия: обычно этот API используется довольно редко (его нельзя использовать из модуля Eclipse). Когда же он все-таки используется, код следует адаптировать для использования соответствующих методов в EclipseStarter.
Затронутые компоненты: все модули.
Описание: в Eclipse 2.1 строка модулей bin.includes в build.properties не должна содержать список JAR-файлов из их объявления библиотек в файле plugin.xml; эти JAR добавлялись свободно. В Eclipse 3.0 список файлов в разделе bin.includes в build.properties является исчерпывающим и должен включать в себя все файлы, которые разработчики модуля намеревались включить в свой модуль при компоновке или экспорте.
Обязательные требования: убедитесь, что строка bin.includes из файла build.properties содержит список всех JAR-файлов, указанных в файле plugin.xml модуля.
Затронутые компоненты: модули, экспортирующие API, включающий элементы из измененного динамического API.
Описание: различные модули экспортируют API, включающий в себя элементы из динамического API. Учитывая описанные здесь изменения в Eclipse 3.0, клиентские модули должны повторно оценить свое использование динамических API в своих API.
Обязательные действия: этот сценарий используется довольно редко, так как изменения динамически подключаемого API Eclipse довольно незначительны. В зависимости от сценария клиенты могут изменить свои API или полагаться на уровень совместимости.
Затронутые компоненты: модули, использующие org.eclipse.core.runtime.Platform.parsePlugins(..., Factory).
Описание: метод org.eclipse.core.runtime.Platform.parsePlugins(...,
Factory)
был перемещен. API, связанный с аргументом Factory, был перемещен из модуля org.eclipse.core.runtime в модуль org.eclipse.core.runtime.compatibility plug-in (зависящий от динамически подключаемого модуля). В результате анализирующий метод был также перемещен.
Обязательное действие: пользователи этого метода должны использовать тот же метод с классом org.eclipse.core.runtime.model.PluginRegistryModel
.
Затронутые компоненты: модули, указывающие код в своих classpath, но не предоставляющие этот код (то есть, JAR предоставляется фрагментом; например, модуль org.eclipse.swt).
Описание: при новом выполнении файлы plug.xml должны быть преобразованы в файлы manifest.mf. Это делается посредством простых преобразований и анализа файлов jar, перечисленных в списке и предоставляемых модулем. В случае если модуль указывает jar в своем classpath, но не предоставляет jar, код для анализа отсутствует и преобразователь модуля не может создать корректный manifest.mf.
Обязательное действие: провайдеры таких модулей должны или поставлять подходящие jar в модуль самостоятельно, либо вручную создать файл META-INF/MANIFEST.MF для своих модулей. Обычно это можно осуществить, используя PDE для получения начального манифеста и последующего добавления в соответствующий заголовок Provide-Package.
Затронутые компоненты: сценарии (то есть файлы Ant build.xml), которые задают classpath, содержащие каталоги классов и jar-файлы, связанные с выполнением.
Описание: в новой версии есть некоторые новые модули и jar-файлы. Их введение обусловлено динамическим рефакторингом в настраиваемые компоненты. Для большинства случаев эти изменения довольно прозрачны. Однако при использовании пользовательских сценариев build.xml (или других похожих), которые в настоящее время компилируют код с org.eclipse.core.runtime
, потребуется обновить их для корректного функционирования. Типичный сценарий содержит запись classpath в задаче <javac>, ссылающуюся на модуль org.eclipse.core.runtime
следующим образом:
../org.eclipse.core.runtime/bin;../org.eclipse.core.runtime/runtime.jar
Динамический модуль по-прежнему содержит большую часть начального динамического кода. Однако различные динамически подключаемые компоненты, используемые только для целей совместимости, содержатся в модулях совместимости (org.eclispe.core.runtime.compatibility
). Большая часть нового динамически подключаемого кода содержится в наборе модулей (org.eclipse.osgi.*
).
Обязательное действие: разработчики должны добавить приведенные ниже записи для устранения ошибок компиляции. Ниже приведен полный список предоставляемых jar-файлов, однако чаще всего требуется лишь некое подмножество в classpath при компиляции. Обычно добавление каталогов /bin зависит от вашего усмотрения. Записи ниже логически сгруппированы по предоставляющим модулям:
Кроме того, эти jar-файлы могут потребоваться в особенных случаях:
При обновлении таких сценариев следует также очистить (то есть удалить) ссылки на org.eclipse.core.boot
. Этот модуль является устаревшим и больше не содержит какой-либо код. Соответствующие записи могли остаться в classpath, но они не выполняют никаких функций и должны быть удалены. Следует удалить:
../org.eclipse.core.boot/bin;../org.eclipse.core.boot/boot.jar
Затронутые компоненты: сценарии (то есть файлы Ant build.xml), использующие задачу eclipse.buildScript.
Описание: компоновщик PDE предоставляет новое свойство в задаче eclipse.buildScript для управления генерацией сценариев компоновки модулей. Это стало возможно при переходе на OSGi.
Обязательные действия: если вы хотите использовать Eclipse 3.0 для компоновки продукта 2.1, добавьте в eclipse.buildScript свойство "buildingOSGi" со значением false. Например:
<eclipse.buildScript ... buildingOSGi="false"/>
Затронутые компоненты: сценарии (то есть файлы Ant build.xml), использующие задачу eclipse.buildScript.
Описание: компоновщик PDE предоставляет новое свойство в задаче eclipse.buildScript для управления генерацией сценариев компоновки модулей. Это стало возможно при переходе на OSGi.
Обязательные действия: если вы хотите использовать Eclipse 3.0 для компоновки продукта 2.1, добавьте в eclipse.buildScript свойство "buildingOSGi" со значением false. Например:
<eclipse.buildScript ... buildingOSGi="false"/>
Затронутые компоненты: сценарии (то есть файлы Ant build.xml), использующие задачу eclipse.buildScript.
Описание: Компоновщик PDE изменил поведение задачи eclipse.fetch для облегчения компоновки Eclipse при автоматической компоновке. Стиль элементов теперь поддерживает только одну запись за раз, а scriptName всегда игнорируется.
Обязательные действия: если у вас есть список записей в теге "elements" в вызове eclipse.fetch call, распространите их между несколькими вызовами в eclipse.fetch. Если вы используете scriptName, обратите внимание, что теперь сгенерированный сценарий fetch всегда называется "fetch_{elementId}". Пример:
<eclipse.fetch elements="plugin@org.eclipse.core.runtime, feature@org.eclipse.platform" .../>
преобразуется в
<eclipse.fetch elements="plugin@org.eclipse.core.runtime" .../> <eclipse.fetch elements="feature@org.eclipse.platform" .../>
Файл install.ini больше не включается в продукт. Вместо него используется файл config.ini, расположенный в каталоге конфигурации. Продукты, использовавшие файл install.ini для указания основного компонента (например, для предоставления информации о торговой марке), должны теперь использовать файл config.ini. Кроме нового имени файла, изменились имена ключей.
Значение ключа feature.default.id в 2.1 должно быть задано в качестве значения нового ключа eclipse.product. Значением eclipse.application должно быть "org.eclipse.ui.ide.workbench".
Наконец, в 2.1 для заставки продукта использовался файл splash.bmp в каталоге презентации модуля. В 3.0 расположение этого изображения указывается явным образом ключом osgi.splashPath в файле config.ini.