Обязательные действия для адаптации механизмов и API версии 3.0

В этом разделе описываются обязательные изменения для приспособления модулей 2.1 к механизмам и API 3.0.

Отказ от работы с org.eclipse.core.runtime.compatibility

Выполнение в Eclipse 3.0 значительно отличается от предыдущих версий. Оно основано на спецификации структуры OSGi. Среда выполнения Eclipse 3.0 включает в себя уровень совместимости (в модуле org.eclipse.core.runtime.compatibility), который управляет API версии 2.1. Разработчикам модулей, желающим повысить производительность и функциональность, рекомендуется использовать API 3.0 и отказаться от зависимости от уровня совместимости. Код совместимости проявляется в трех местах:

Далее подробно объясняется, какие классы и методы присутствуют для обеспечения совместимости, а также дается руководство по обновлению модулей.

Модули и комплекты

The Eclipse runtime has been refactored into two parts; classloading and prerequisite management, and extension/extension-point management. Это разделение позволяет легко и прозрачно применить спецификации структуры OSGi для управления загрузкой классов и предварительными требованиями. Это, в свою очередь, предоставляет новые возможности выполнения, от динамически выполняемых установки/обновления/удаления модуля до обеспечения безопасности и повышения настраиваемости.

Несмотря на то, что мы продолжаем говорить о модулях, в новой среде модули на самом деле являются комплектами с определенными расширениями и точками расширений. Термин комплект определен спецификацией структуры OSGi и подразумевает набор типов и ресурсов и связанные меж-комплектные сведения о предварительных требованиях. Реестр расширений является новой формой реестра модулей и содержит сведения только о расширениях и точках расширения. По большому счету API реестра расширений тот же, что и соответствующий API реестра модулей (дополнительные сведения содержатся в разделе Реестры).

В среде выполнения Eclipse 2.x объект модуля имел несколько ролей и обязанностей:

В Eclipse 3.0 эти роли и ответственности выделены в отдельные объекты.

Комплект
Комплектами называются единицы модульности OSGi. Для каждого комплекта есть свой загрузчик классов, и можно создать графики зависимости загрузки классов между комплектами. Жизненный цикл комплектов состоит из пуска и остановки, и структура OSGi сообщает о связанных с комплектами событиях (то есть об установке, обработке, запуске, остановке, удалении из системы и т.д.) заинтересованным сторонам. В отличие от класса Eclipse Plugin, класс OSGi Bundle не расширяемый. Таким образом, разработчики не могут создавать собственные классы комплектов.
BundleActivator
BundleActivator - это интерфейс, определяемый структурой OSGi. Каждый комплект может задать класс активации комплекта, что можно сравнить с определением модулем класса Plugin. Экземпляр заданного класса создается структурой и используется для обработки start() и stop() жизненного цикла. Однако есть существенное отличие в природе обработки этого жизненного цикла. В Eclipse принято (хотя и не рекомендуется), чтобы классы Plugin выполняли и инициализацию, и регистрацию. В OSGi активаторы должны выполнять только регистрацию. Выполнение больших объемов инициализации (или других задач) в BundleActivator.start() снижает быстродействие системы.
BundleContext
BundleContexts - это механизм OSGi для анонсирования общих функций системы отдельным комплектам. Каждый комплект обладает уникальным экземпляром private BundleContext, который они могут использовать для доступа к системной функции (например, getBundles() для обнаружения всех комплектов системы).
Модуль
Новый Plugin очень похож на оригинальный класс Plugin Eclipse, со следующими исключениями: объекты Plugin больше не являются обязательными или управляемым во время выполнения, а некоторые методы устарели. По сути это удобный механизм хостинга для полезных функций или механизмов, но он более не является обязательным. Многие предоставляемые им функции, теперь доступны динамически с помощью класса Platform.

Plugin также реализует BundleActivator. Удобнее иметь один центральный объект, представляющий жизненный цикл и семантику модуля. Обратите внимание, что это не оправдывает активную инициализацию структур данных, широко используемую в модулях. Мы подчеркиваем, что модули могут быть активированы потому, что какой-то периферийный класс был упомянут во время проверки класса в каком-то другом модуле. Таким образом, тот факт, что модуль был активирован, не означает, что потребовались его функции. Также обратите внимание, что вы можете задать другой класс BundleActivator или вообще не использовать активатор комплекта.

Необходимые для переноса класса Plugin 2.x в Eclipse 3.0 шаги зависят от выполняемых классом функций. Как упоминалось выше, в большинстве случаев работа жизненного цикла запуска попадает в одну из следующих категорий:

Инициализация
Инициализация структуры данных и модели зачастую происходит в Plugin.startup(). Логичным казалось бы выполнять эту работу в BundleActivator.start(), что позволило бы оставить эту функцию вPlugin. Это нежелательно. Как и в случае с модулями 2.x, модули и комплекты 3.0 могут быть запущены по многим причинам и во многих различных обстоятельствах.
Можно прояснить этот вопрос с помощью примера времен Eclipse 2.0. Имелся модуль, инициализировавший крупную модель, что требовало загрузки 11 Мб кода и многих мегабайт данных. Довольно часто этот модуль активировался чтобы выяснить, следует ли помечать определенным образом значок проекта, отображенный в окне навигатора. Этот тест не требовал выполнения инициализации в startup(), но, тем не менее, все пользователи во всех случаях страдали от загрузки памяти и снижения производительности из-за этой ненужной инициализации.
Альтернативный подход предлагает выполнять такую инициализацию в классическом неспешном стиле. Например, вместо инициализации модели при активации модуля/комплекта можно провести ее при возникновении реальной необходимости (например, с помощью метода доступа централизованной модели). Во многих случаях на это потребуется примерно столько же времени, но для других сценариев этот подход отложит инициализацию (возможно навсегда). Рекомендуется во время переноса модулей 2.1 пересмотреть используемую стратегию инициализации.
Регистрация
Запуск модуля является подходящим моментом для регистрации получателей запросов, служб и т.д. и пуска фоновых нитей (например, прослушивание сокета). Plugin.start() как раз подходит для выполнения это работы. Также имеет смысл отложить ее до срабатывания другого триггера (например, вызова определенной функции или элемента данных).
Глобальные данные модуля
Класс Plugin может по-прежнему выполнять эту роль. Вопрос в том, что объекты Plugin больше не являются глобально доступными посредством управляемого системой списка. В Eclipse 2.x можно найти любой объект Plugin модуля с помощью реестра модулей. Теперь это стало невозможным. В большинстве случаев такой тип доступа и не требуется. Модули, доступные через реестр, обычно используются как базовые модули, а не для вызова специфичных для домена методов. Эквивалентный уровень функциональности можно получить благодаря доступу и управлением соответствующими объектами комплектов.

Реестры и модель модуля

В новой среде выполнения есть разделение между информацией и структурой, необходимой для выполнения модуля и сведениями, относящимися к расширениям и точкам расширения модуля. Первые определяются и управляются спецификацией структуры OSGi. Вторые являются концепциям, специфичными для Eclipse, и добавляются с помощью динамически выполняемого кода Eclipse. Соответственно, оригинальный реестр модулей и связанные объекты были разделены на комплекты OSGi и реестр расширений Eclipse.

Компоненты IPluginRegistry, имеющие дело с выполнением спецификаций (например, IPluginDescriptor, ILibrary, IPrequisite) были признаны устаревшими, а остальные компоненты, связанные с расширениями и точками расширений, были перемещены в IExtensionRegistry. Кроме того, так называемые объекты моделей, связанные с реестром модулей, также устарели. Эти типы были создаются в среде выполнения в основном для поддержки таких утилит, как PDE. К сожалению, зачастую уровень требуемой информации превышал возможности выполнения (например, запоминание номеров строк элементов в plugin.xml) и в конце концов потенциальные потребители информации выполнения были вынуждены использовать собственные структуры.

В новой версии мы заново оценили функции, предоставляемые средой выполнения, и теперь поставляем только те, которые либо жизненно необходимы для выполнения или слишком сложны, чтобы их создали другие. Как упоминалось ранее, объекты моделей реестра модулей устарели, как и API анализа модуля. Новый реестр расширений хранит важную связанную с расширениями информацию. Новая структура состояния (см. org.eclipse.osgi.service.resolver.State и связанные разделы) предоставляет управление важнейшей связанной с расширениями информацией.

Структура фрагмента NL

В Eclipse 3.0 структура фрагмента NL была обновлена и стала более согласованной. Ранее перевод файлов, таких как plugin.properties, входил внутрь JAR-файлов, предоставляемых фрагментами. Так как оригинальные файлы можно найти в корневом каталоге соответствующего модуля-хоста, при более согласованном размещении переведенные файлы будут расположены в корневом каталоге фрагментов NL. Например,

  org.eclipse.ui.workbench.nl/
     fragment.xml
     plugin_fr.properties
     plugin_pt_BR.properties
     ...
     nl1.jar

Обратите внимание, что файл nl1.jar ранее содержал переводы для plugin.properties. Эти файлы теперь находятся в корневом каталоге фрагмента, и JAR содержит переводы всех ресурсов (то есть файлов, загружаемых через загрузчик классов) в модуле хоста.

Конечно, структура фрагментов Eclipse 2.1 NL по-прежнему поддерживается для модулей 2.1, выполняемых в Eclipse 3.0. Тем не менее, нельзя использовать фрагмент 2.1 NL в модуле 3.0. Фрагмент должен быть обновлен для новой структуры.

Обзор изменений API

org.eclipse.core.boot (пакет org.eclipse.core.boot)

Весь пакет org.eclipse.core.boot устарел. BootLoader был объединен в org.eclipse.core.runtime.Platform так как более не имеет смысла разделять загрузку и выполнение. Обратите внимание, что модуль org.eclipse.core.boot был разбит, и его код был перемещен в среду выполнения или уровень совместимости.

IPlatformConfiguration всегда был типом, задаваемым и используемым компонентом установки и обновления Eclipse. Вследствие реорганизации среды выполнения этот тип обрел свой родной дом. Класс остался по большей части без изменений и теперь входит в пакет org.eclipse.update.configurator.IPlatformConfiguration.

IPlatformRunnable был перемещен в org.eclipse.core.runtime.IPlatformRunnable.

IExtension и IExtensionPoint (пакет org.eclipse.core.runtime)

Метод getDeclaringPlugin() (в обоих классах) предоставляет ссылку к модулю, объявляющему расширение или точку расширения (соответственно). Новая модель реестра разделяет аспекты выполнения модулей и аспекты расширения/точки расширения и более не содержит IPluginDescriptors. Пользователям этого API рекомендуется использовать новый метод getParentIdentifier(), содержащийся как в IExtension, так и в IExtensionPoint.

ILibrary, IPluginDescriptor, IPluginRegistry и IPrerequisite (пакет org.eclipse.core.runtime)

В оригинальной среде выполнения реестр модулей сохранял полный снимок конфигурации среды выполнения. В Eclipse 3.0 эта информация разделена между структурой OSGi и реестром расширений. Сами по себе эти классы устарели. Информация об устаревших функциях содержат рекомендации по обновлению кода.

Platform и Plugin (пакет org.eclipse.core.runtime)

В новой версии объекты Plugin более не управляются средой выполнения и не могут быть доступны в целом через платформу. Также и реестр модулей более не существует и не предоставляет доступ к описателям модуля. Вместо этого есть методы для их замещения, которые описаны в Javadoc устаревших методов в этих классах.

org.eclipse.core.runtime.model (пакет org.eclipse.core.runtime.model)

Все типы этого пакета устарели. Дополнительные сведения содержатся в описании реестров.

IWorkspaceRunnable и IWorkspace.run (пакет org.eclipse.core.resources)

Клиенты метода IWorkspace.run(IWorkspaceRunnable,IProgressMonitor) должны изменить работу с этим методом и перейти на использование более полного метода IWorkspace.run(IWorkspaceRunnable,ISchedulingRule,int,IProgressMonitor). Старый метод IWorkspace.run блокируется во всей рабочей области на время действия IWorkspaceRunnable. Это означает, что осуществляемая с помощью этого метода операция не сможет быть выполнена одновременно с другими операциями, изменяющими рабочую область. В Eclipse 3.0 многие долго выполняемые операции были перемещены в фоновые нити, поэтому вероятность конфликтов между операциями значительно возросла. Если модальная интерактивная операция блокируется долго выполняемой фоновой операцией, пользовательский интерфейс замораживается до завершения фоновой операции или до отмены одной из операций.

Рекомендованным решением в данной ситуации является переключение работы с IWorkspace.run на новый метод с параметром правила расписания. Правило расписания должно быть самым точным правилом, управляющим правилами для всех изменений данной операции. Если операция пытается изменить ресурсы за пределами области действия правила расписания, возникает исключительная ситуация времени выполнения. Точное правило расписаний, обязательное для определенной операции рабочей области, не задано, и может изменяться в зависимости от типа хранилища в определенном проекте. Для получения правила расписания изменяющей ресурс операции следует использовать фабрику IResourceRuleFactory. При необходимости можно использовать MultiRule для задания нескольких правил ресурсов, а метод MultiRule.combine можно использовать для сочетания правил из различных изменяющих ресурсы операций.

Если не требуется блокировка, можно использовать правило расписания null. Это позволит изменять все ресурсы рабочей области, но не помешает параллельному изменению рабочей области другими нитями. Для внесения простых изменений в рабочую область это является зачастую самым простым и дружественным решением.

IWorkbenchPage (пакет org.eclipse.ui)

IEditorDescriptor (пакет org.eclipse.ui)

ISharedImages (пакет org.eclipse.ui)

IWorkbenchActionConstants (пакет org.eclipse.ui)

IWorkbenchPreferenceConstants (пакет org.eclipse.ui)

IExportWizard (пакет org.eclipse.ui)

IImportWizard (пакет org.eclipse.ui)

INewWizard (пакет org.eclipse.ui)

WorkbenchHelp (пакет org.eclipse.ui.help)

IHelp (пакет org.eclipse.help)

ITextEditorActionConstants (пакет org.eclipse.ui.texteditor)

IAbstractTextEditorHelpContextIds (пакет org.eclipse.ui.texteditor)

BasicTextEditorActionContributor (пакет org.eclipse.ui.texteditor)

TextEditorActionContributor (пакет org.eclipse.ui.editors.text)

Точка расширения annotationTypes (модуль org.eclipse.ui.editors)

Теперь тип аннотаций указывается явно. См. Annotation.getType() и Annotation.setType(). Тип аннотации может изменяться динамически. Для объявления типов аннотаций была добавлена новая точка расширения: "org.eclipse.ui.editors.annotationTypes". Тип аннотации имеет имя и может быть объявлен производным типом другого объявленного типа аннотации. Объявление типа аннотации также может использовать атрибуты "markerType" и "markerSeverity" для того, чтобы указать, что маркеры данного типа и уровня серьезности должны быть представлены в текстовых редакторах в качестве аннотаций определенного типа. Атрибуты "markerType" и "markerSeverity" в "org.eclipse.ui.editors.markerAnnotationSpecification" более не следует использовать. Тем самым спецификации аннотаций маркера становятся независимыми от маркеров, и их имя может ввести в заблуждение. Однако имя сохраняется для обеспечения совместимости с предыдущими версиями.

Экземпляры производных классов AbstractMarkerAnnotationModel автоматически обнаруживают и задают корректные типы аннотаций, которые создаются из маркеров. Для программного извлечения типа аннотаций для определенного маркера или определенной пары markerType и markerSeverity используйте org.eclipse.ui.texteditor.AnnotationTypeLookup.

Доступ к иерархии типов аннотаций обеспечивается IAnnotationAccessExtension. Для данного типа аннотаций можно получить цепочку надтипов и проверить, является ли тип аннотации производным типом другого типа. DefaultMarkerAnnotationAccess реализует этот интерфейс.

Точка расширения markerAnnotationSpecification (модуль org.eclipse.ui.editors)

Тип аннотации является ключом, с помощью которого можно найти спецификацию связанной аннотации маркера. Так как типы аннотаций могут расширить другие типы аннотаций, между аннотациями маркеров также существует неявная связь. Таким образом, спецификация аннотации маркера заданного типа осуществляется с помощью спецификаций аннотаций для надтипов данного типа. Поэтому спецификацию аннотации маркера необязательно завершать, как это требовалось ранее. Спецификации аннотаций маркера можно получить с помощью AnnotationPreferences. Используя org.eclipse.ui.texteditor.AnnotationPreferenceLookup, можно получить свойства аннотаций для данного типа, который автоматически заполняет свойство в цепочке надтипа комментария.

Спецификация аннотаций маркеров была расширена тремя дополнительными атрибутами для того, чтобы разрешить определение настраиваемого вида данных типов аннотаций в вертикальной линейке. Этими атрибутами являются "icon", "symbolicIcon" и "annotationImageProvider". Значением "icon" является путь к файлу, содержащему изображение значка. Значением "symbolicIcon" может быть "error", "warning", "info", "task" или "bookmark". Атрибут "symbolicIcon" используется, чтобы сообщить платформе, что аннотация должна быть отображена с помощью изображений, используемых платформой соответственно для сообщений об ошибках, предупреждениях, информационных, задач и закладок. Значением "annotationImageProvider" является класс, реализующий org.eclipse.ui.texteditor.IAnnotationImageProvider, что позволяет полностью настроить вид аннотации.

Вертикальная линейка использует связанные с ней IAnnotationAccess/IAnnotationAccessExtension для прорисовки аннотаций. Вертикальная линейка более не вызывает Annotation.paint. Вообще аннотации больше не должны прорисовывать сами себя. Методы "paint" и "getLayer" были признаны устаревшими для того, чтобы сделать аннотации независимыми от пользовательского интерфейса. DefaultMarkerAnnotationAccess выступает реализацией по умолчанию для IAnnotationAccess/IAnnotationAccessExtension. DefaultMarkerAnnotationAccess реализует следующую стратегию для прорисовки аннотаций: если аннотация реализует IAnnotationPresentation, вызывается IAnnotationPresentation.paint. Если нет, происходит поиск поставщика изображения аннотации в свойствах аннотации. Поставщик изображения аннотаций доступен только в том случае, если он указан, и если модуль, задающий спецификацию аннотации, уже был загружен. Если есть поставщик изображения аннотации, то вызов перенаправляется к нему. Если нет, используется указанный значок "icon". "symbolicIcon" используется как запасной вариант. Для прорисовки аннотаций важен уровень презентации аннотации. DefaultMarkerAnnotationAccess находит уровень презентации с помощью следующей стратегии: если свойство аннотации указывает презентационный уровень, используется этот уровень. Если уровень не указан и аннотация реализует IAnnotationPresentation, используется IAnnotationPresentation.getLayer.

Переход на точку расширения annotationTypes (модуль org.eclipse.ui.editors)

Модуль org.eclipse.ui.editors объявляет следующие типы аннотаций:

   <extension point="org.eclipse.ui.editors.annotationTypes">
      <type
         name="org.eclipse.ui.workbench.texteditor.error"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="2">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.warning"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="1">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.info"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="0">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.task"
         markerType="org.eclipse.core.resources.taskmarker">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.bookmark"
         markerType="org.eclipse.core.resources.bookmark">
      </type>
   </extension>

Заданное расширение markerAnnotationSpecification больше не предоставляет атрибуты "markerType" и "markerSeverity". Они задают атрибут "symbolicIcon" с соответствующим значением. Таким образом, MarkerAnnotation.paint и MarkerAnnotation.getLayer больше не вызываются, то есть, переопределение этих методов не оказывает никакого воздействия. Попадающие под влияние этого изменения клиенты должны использовать IAnnotationPresentation.

ILaunchConfigurationType (package org.eclipse.debug.core)

С введением расширяемых режимов запуска в версии 3.0 для каждого типа конфигурации запуска может существовать более одного делегата запуска. Предыдущие версии поддерживали только одного делегата запуска для каждого типа конфигурации запуска. Метод ILaunchConfigurationType.getDelegate() теперь считается устаревшим. Вместо него следует использовать метод getDelegate(String mode) для получения делегата запуска для определенного режима запуска. Устаревший метод был изменен для возврата делегата запуска для режиме run.

ILaunchConfigurationTab and ILaunchConfigurationTabGroup (пакет org.eclipse.debug.ui)

Группы вкладок запуска и вкладки запуска больше не уведомляются по завершении запуска. Метод launched(ILaunch) в интерфейсах ILaunchConfigurationTab и ILaunchConfigurationTabGroup признан устаревшим и больше не вызывается. Этот метод запуска всегда создавал проблемы, так как вкладки существовали только при запуске из окна диалога запуска. Также, после введения запуска в фоновом режиме этот метод больше не вызывается, так как диалог запуска закрывается до создания конечных объектов запуска.

ILaunchConfigurationTab и AbstractLaunchConfigurationTab (пакет org.eclipse.debug.ui)

В интерфейс ILaunchConfigurationTab были добавлены два метода - activated и deactivated. Это новые методы жизненного цикла вызываются соответственно при входе на вкладку и выходе из нее. Имеющиеся реализации ILaunchConfigurationTab, являющегося производным классом абстрактного класса, предоставляемого модулем отладки (AbstractLaunchConfigurationTab), являются двоично совместимыми, так как методы реализованы в абстрактном классе.

В предыдущих версиях вкладке отправлялось сообщение initializeFrom при активации и performApply при деактивации. Таким образом, структура вкладок конфигурации запуска предоставляла связь между вкладками посредством конфигурации запуска, за счет обновления конфигурации текущими значениями атрибутов при выходе из вкладки и обновления вновь созданной вкладки. Тем не менее, так как многие вкладки не поддерживают взаимодействие между вкладками, этого может оказаться недостаточно. Также не было возможности отличить активированную вкладку и вкладку, отображающую выбранную конфигурацию запуска впервые. Новые методы позволяют вкладкам различать активацию, инициализацию, деактивацию и сохранение текущих значений.

По умолчанию реализация метода activated, предоставляемая абстрактной вкладкой, вызывает initializeFrom. Реализация по умолчанию метода deactivated вызывает performApply. Вкладки, желающие использовать преимущества нового API, должны переопределить эти методы. Обычно для вкладок, не поддерживающих взаимодействие между вкладками, рекомендуется повторно реализовать эти методы, чтобы они ничего не делали.

Тип точки расширения launchConfigurationTabGroup (пакет org.eclipse.debug.ui)

В предыдущих версиях переключение проекций задавалось в конфигурации запуска через атрибуты конфигурации запуска ATTR_TARGET_DEBUG_PERSPECTIVE и ATTR_TARGET_RUN_PERSPECTIVE. В появлением расширяемых режимов запуска в версии 3.0 этот подход больше не оптимален. Теперь переключение проекций задается на основе типа конфигурации запуска для каждого режима запуска, поддерживаемого конфигурацией запуска. В DebugUITools был добавлен API для установки и получения проекции, связанной с типом конфигурации запуска для определенного режима запуска.

Дополнительно был добавлен необязательный элемент launchMode к точке расширения launchConfigurationTabGroup, позволяющий добавленной группе вкладок указывать проекцию по умолчанию для типа и режима конфигурации запуска.

Из пользовательского интерфейса Eclipse можно редактировать проекцию, связанную с типом конфигурации, открыв окно диалога конфигурации запуска и выбрав узел типа конфигурации запуска в дереве (а не отдельную конфигурацию). Отображение вкладки позволяет пользователю задать проекцию с каждым поддерживаемым режимом запуска.

[Только для JDT] IVMRunner (package org.eclipse.jdt.launching)

В класс VMRunnerConfiguration были добавлены два метода для поддержки задания и получения переменных среды. Реализующие классы IVMRunner должны вызывать VMRunnerConfiguration.getEnvironment() и передавать эту среду в рабочую JVM. Клиенты, использующие DebugPlugin.exec(String[] cmdLine, File workingDirectory) могут сделать это, вызывая DebugPlugin.exec(String[] cmdLine, File workingDirectory, String[] envp). Достаточно простой передачи результатов из getEnvironment().

[Только для JDT] VMRunnerConfiguration и классы Bootstrap (пакет org.eclipse.jdt.launching)

В предыдущих версиях VMRunnerConfiguration имел один атрибут для описания пути загрузки. Атрибут является набором Strings, указываемых в аргументе Xbootclasspath. В VMRunnerConfiguration были добавлены три новых атрибута для поддержки JVM, позволяющих вносить добавления в начало и конец пути загрузки. Новыми добавленными методами и атрибутами являются:

Старый атрибут getBootClassPath() по-прежнему существует и содержит эквивалент полного пути к этим трем атрибутам. Однако VMRunners, поддерживающие опции нового пути загрузки, должен воспользоваться преимуществами новых атрибутов.

[Только для JDT] Улучшенная поддержка работающих копий (пакет org.eclipse.jdt.core)

Функция работающей копии модели Java была доработана в версии 3.0 для повышения ее функциональности. До выпуска версии 3.0 модель Java позволяла создавать отдельные работающие копии компиляторов. В работающую копию можно было внести изменения и затем зафиксировать их. Имелась поддержка ограниченного анализа работающей копии в контексте остальной модели Java. Тем не менее, эти анализаторы могли работать только с одной копией.

Изменения в 3.0 позволяют создавать наборы работающих копий компиляторов, управлять ими и выполнять анализ в присутствии всех рабочих копий группы. Например, теперь стало возможно для клиентов наподобие JDT выполнять рефакторинг для создания работающих копий для одного или нескольких компиляторов, что считается изменениями, и затем обрабатывать ссылки типов между работающими копиями. Ранее это было возможно только после внесения изменений в рабочие копии модуля компиляции.

В API модели Java были внесены два изменения для добавления этой улучшенной поддержки:

(1) Функциональность, присущая ранее IWorkingCopy и наследуемая ICompilationUnit была перенесена в ICompilationUnit. Интерфейс IWorkingCopy ранее использовался только в этой ситуации и был в целом более общим, чем это требовалось. Данное изменение упрощает API. IWorkingCopy теперь считается устаревшим. Другие ситуации в API, где IWorkingCopy используется как параметр или конечный тип, также признаны устаревшими. Теперь в API используется метод ICompilationUnit вместо IWorkingCopy.

(2) Интерфейс IBufferFactory был заменен на WorkingCopyOwner. Улучшенная поддержка рабочих копий требует, чтобы имелся объект, владеющий рабочими копиями. Несмотря на наличие IBufferFactory, имя не вполне адекватно передает то, как работает новый механизм рабочих копий. WorkingCopyOwner - намного более наглядное имя. Кроме того, WorkingCopyOwner объявляется как абстрактный класс, а не интерфейс, что делает возможным последующее развитие и доработку владельца рабочих копий. Один метод IBufferFactory перемещается в WorkingCopyOwner без изменений. WorkingCopyOwner не реализует IBufferFactory, чтобы подчеркнуть, что IBufferFactory устарел. IBufferFactory теперь считается устаревшим. Другие ситуации в API, где IBufferFactory появляется как параметр или результирующий тип, также признаны устаревшими. Теперь в API используются методы, применяющие WorkingCopyOwner вместо IBufferFactory.

Эти изменения не нарушают двоичную совместимость.

При переносе все ссылки на тип IWorkingCopy должны вместо него ссылаться на ICompilationUnit. Реализация IWorkingCopy применяет также и ICompilationUnit, что означает, что объекты типа IWorkingCopy можно преобразовать к типу ICompilationUnit.

Класс, реализующий IBufferFactory, должен быть заменен производным классом WorkingCopyOwner. Несмотря на то, что WorkingCopyOwner не реализует сам IBufferFactory, возможно объявить производный класс WorkingCopyOwner, реализующий IBufferFactory, таким образом связав старый и новый код (IBufferFactory объявляет createBuffer(IOpenable), тогда как WorkingCopyOwner объявляет createBuffer(ICompilationUnit); ICompilationUnit расширяет IOpenable).

Так как изменения, затрагивающие IWorkingCopy и IBufferFactory взаимосвязаны, рекомендуется внести изменения в оба объекта. Ниже показан пример объявления:

Реструктурирование модуля org.eclipse.help

Модуль org.eclipse.help, используемый для хранения API и точек расширения для добавления и расширения системы справки и отображения справки, теперь содержит лишь API и точки расширения для добавления справочных ресурсов и доступа к ним. Часть реализации пользовательского интерфейса справки по умолчанию, содержавшаяся в этом модуле, была перемещена в новый модуль org.eclipse.help.base вместе с API для расширения реализации. API и точка расширения для добавления пользовательского интерфейса справки и отображения справки были перемещены в модуль org.eclipse.ui. Эта реструктуризация позволяет повысить гибкость приложений относительно системы справки. Новая структура позволяет приложениям, основанным на рабочей среде, предоставлять собственные пользовательские интерфейсы справки и/или реализации справки, либо же полностью отказаться от использования системы справки.

Так как затрагиваемые точки расширения и пакеты API предназначаются только для использования самой системой справки, вряд ли имеющиеся модули будут затронуты этим изменением. Они указаны здесь лишь для полноты картины:

Новый API пользовательского интерфейса поиска

В версии 3.0 был добавлен новый API для реализации пользовательского поиска. Исходный API считается устаревшим в версии 3.0, и рекомендуется переход клиентов на новый API, содержащийся в пакетах org.eclipse.search.ui и org.eclipse.search.ui.text.

Клиентам необходимо создать реализации ISearchQuery, ISearchResult и ISearchResultPage. Реализация ISearchResultPage затем должна быть добавлена в новую точку расширения org.eclipse.search.searchResultViewPages.

Реализации ISearchResult и ISearchResultPage по умолчанию предоставляются в пакете org.eclipse.search.ui.text.

Сообщения null в MessageBox и DirectoryDialog (пакет org.eclipse.swt.widgets)

До выпуска версии 3.0 вызов DirectoryDialog.setMessage(String string) или MessageBox.setMessage(String string) SWT с нулевым значением для строки вел к появлению окна диалога с отсутствующим текстом заголовка. Это поведение было произвольным (передача null никогда не была разрешена) и создавало проблемы с getMessage, которому не разрешается возвращать null. В версии 3.0 передача нулевого результата ведет к возникновению исключительной ситуации IllegalArgumentException, и для отражения этого были изменены спецификации, благодаря чему это было приведено в соответствие с методом их надкласса Dialog.setMessage. При использовании Dialog.setMessage убедитесь в том, что передаваемая строка не содержит нулевое значение. Если требуется создать окно с пустым заголовком, просто передайте пустую строку.

Усовершенствование модального окна состояния

Поддержка выполняемых одновременно операций требует более совершенных способов отображения модального окна состояния. В классе IProgressService была применена дополнительная поддержка окна состояния при повышении времени реакции системы. Имеющийся способ отображения окна состояния с помощью ProgressMonitorDialog по-прежнему работает. Однако рекомендуется перейти на использование IProgressService.

В разделе Отображение модального окна состояния в Eclipse 3.0 содержится описание переход на IProgressService.

Удалены группы действий отладки

Точка расширения Группы действий отладки (org.eclipse.debug.ui.debugActionGroups) была удалена. В Eclipse 3.0 рабочая среда обеспечивает поддержку групп действий с помощью точки расширения org.eclipse.platform.ui.activities. Эта поддержка предоставляет все, что ранее предоставляла группа действий отладки, но ее легче использовать (она поддерживает шаблоны вместо исчерпывающего указания всех действий), и они имеет программный вспомогательный API. Невозможность удалить ссылки на старую точку расширения не причинит беспокойств. Эти ссылки будут просто проигнорированы. Производителям программных продуктов рекомендуется использовать поддержку групп действий рабочей средой для связи специфических для языка действий отладчика со специфическими для языка действиями (например, действия отладки C++ можно связать с группой действий "Разработка C++").

Диспетчер точек прерывания может быть отключен

IBreakpointManager теперь задает методы setEnabled(boolean) и isEnabled(). Когда диспетчер точек прерывания отключен, отладчики должны игнорировать все зарегистрированные точки прерывания. Платформа отладки также предоставляет новый механизм получателей запросов - IBreakpointManagerListener, позволяющий клиентам регистрироваться у диспетчера точек прерывания, чтобы получать уведомления при изменениях. Панель Точки прерывания вызывает этот API из нового действия переключения, что позволяет "Пропустить все точки прерывания". Отладчики, не учитывающие активность диспетчера точек прерывания, не будут правильно функционировать, если пользователь попытается использовать этот комплект.

[Только для JDT] Участники поиска Java (пакет org.eclipse.jdt.core.search)

Схожие с Java языки (вроде JSP, SQLJ, JWS и так далее) должны уметь принимать участие в поиске Java. В частности, реализующие классы таких языков должны уметь:

Такой реализующий класс называется участником поиска. Он расширяет класс SearchParticipant. Участники поиска передаются запросам поиска (см. SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)).

Для индексации или поиска совпадений участнику поиска требуется определить производный класс SearchDocument, который сможет получить содержимое документа, переопределив getByteContents() или getCharContents(). Экземпляр этого производного класса возвращается в getDocument(String).

Участник поиска, желающий проиндексировать некоторый документ, будет использовать SearchParticipant.scheduleDocumentIndexing(SearchDocument, IPath) для расписания индексации определенного документа в определенном индексе. Когда документ готов к индексации, базовая структура вызывает SearchParticipant.indexDocument(SearchDocument, IPath). Затем участник поиска получает содержимое документа, анализирует его и добавляет записи индекса, используя SearchDocument.addIndexEntry(char[], char[]).

После завершения индексации можно запросить индекс и обнаружить совпадения с помощью SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor). При этом вначале будут опрошены участники поиска на предмет индексов, требуемых для данного запроса, с помощью SearchParticipant.selectIndexes(SearchPattern, IJavaSearchScope). Для каждой записи индекса, совпадающей с заданным шаблоном, создается документ поиска с помощью опроса участника поиска (см. getDocument(String)). Все эти документы передаются участнику поиска, чтобы он смог обнаружить совпадения с помощью locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor). Участник поиска уведомляет SearchRequestor о совпадениях поиска с помощью acceptSearchMatch(SearchMatch) и передавая экземпляр производного класса SearchMatch.

Участник поиска может делегировать часть своей работы участнику поиска Java, используемому по умолчанию. Можно получить экземпляр этого участника, используемого по умолчанию, с помощью SearchEngine.getDefaultSearchParticipant(). Например, при запросе на обнаружение совпадений участник SQLJ может создать документы .java из своих документов .sqlj и делегировать работу используемому по умолчанию участнику с помощью передачи документов .java.