Как выражать зависимости между проектами в Eclipse PDE

Я ищу наилучшую практику обработки зависимостей между проектами между смешанными типами проектов, где некоторые из проектов - проекты с подключаемым модулем eclipse/OSGI (приложение RCP), а другие - просто старые Java-проекты (модули веб-сервисов). Немногие из плагинов eclipse имеют зависимости от проектов Java.

Моя проблема в том, что, по крайней мере, насколько я понял, нет никакого способа четко выразить такую ​​зависимость в среде Eclipse PDE. Я могу иметь проекты подключаемых модулей, зависящие от других подключаемых проектов (через Import-Package или Require-Bundle манифеста заголовков), но не от простых java-проектов.

Кажется, у меня есть проект, который может объявить зависимость от jar из другого проекта в рабочей области, но эти файлы jar не получают ни экспорт, ни запуск конфигурации (хотя редактирование кода Java видит, что библиотеки просто отлично).

"Проекты Java" используются для создания служб, которые будут развернуты в контейнере J2EE (JBoss 4.2.2 на данный момент), и в некоторых случаях выпускают несколько баннеров - один для развертывания на ухе JBoss и другой для использования клиентом кода (приложение RCP).

То, как мы "решили" эту проблему на данный момент, состоит в том, что у нас есть еще две конфигурации пусковых установок внешних устройств - одна для сборки всей банки и другая для копирования этих банок в проекты подключаемого модуля. Это работает (вроде), но цели "целая сборка" и "копировать банки" имеют довольно большой шаг сборки, минуя всю инкрементную функцию построения затмения и копируя банки вместо того, чтобы просто ссылаться на проекты. Я развязываю информацию о зависимостях и запрашивает довольно массовое обновление рабочей области, которое ест время разработки, как будто это была конфета.

То, что я хотел бы иметь, - это гораздо более "естественная" настройка рабочего пространства, которая будет управлять зависимостями между проектами и запрашивать инкрементные перестройки только по мере необходимости, иметь возможность использовать код клиента из библиотек служб в плагинах приложений RCP и иметь возможность запускать приложение RCP со всеми необходимыми классами, где они необходимы.

Так что я могу взять пирог и съесть его;)

Примечание

Чтобы быть ясным, речь идет не только об управлении зависимостями и управлении модулем на данный момент, как о конфигурации Eclipse PDE.

Я хорошо знаю такие продукты, как [Maven], [Ivy] и [Buckminster], и они решают совершенно другую проблему (как только я решил проблему с настройкой рабочей области, эти продукты могут быть полезны для материализации рабочего пространства и построение продукта)

Ответ 1

Я никогда не делал этого, это теоретический подход. Но я бы попробовал систему управления зависимостями, такую ​​как плющ или maven2.

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

Ответ 2

Проекты Eclipse зависят друг от друга благодаря флажку в свойствах проекта (зависимые проекты?), которые, как Eclipse решает, что строить. Вы можете установить это самостоятельно, но обычно это задается при изменении пути сборки Java. Он хранит данные в файле .project IIRC, поэтому, пройдя через графический интерфейс и увидев, какие изменения, вы можете быть более гибкими в том, как вы применяете другие.

Однако, похоже, вы хотите смешивать и сопоставлять Jars and Bundles. Легкий способ сделать это - просто рассматривать все проекты как проекты Java. В проекте PDE вы можете входить и настраивать путь сборки Java; он будет жаловаться и говорить, что это неправильный способ сделать это, но это позволит вам зависеть от проекта PDE от проекта Java без всякого пушистого JARing. Сказав это, меня не удивило бы, если бы были проблемы с выполнением этого подхода - среда выполнения PDE, скорее всего, не увидит этого.

Другой подход состоит в том, чтобы сделать ваши JAR сами пакетами PDE/OSGi. В конце концов, пакет OSGi - это не что иное, как JAR с небольшим количеством лишней жесткости в манифесте, и это позволит вам разрабатывать и собирать ваши проекты тривиально, используя автоматическое управление зависимостями. Вероятно, это самый простой способ, даже если вам действительно не нужно, чтобы манифест присутствовал в ваших пакетах. Но это будет означать, что ваше приложение PDE может быть отправлено с более модульным подходом, а не при необходимости встраивать библиотеки в каждый плагин.

Итак, PDE может генерировать пакеты OSGi, и это просто другое имя для JAR + Manifest. Вы можете использовать JAR точно так же в других средах (например, для вашего EAR или других пользователей), и вы можете использовать уровень OSGi в своем приложении. Там действительно нет причин не делать этого, учитывая тип гибридного пакета, о котором вы говорите.

Ответ 3

В нашем решении используется конструктор Ant для копирования каталогов классов простых Java-проектов непосредственно в верхний каталог проекта плагина. Мы пропускаем шаг построения JAR, чтобы сэкономить время, и он работает очень хорошо. Если проект плагина зависит от внешних JAR, которые уже созданы, мы также копируем их.

Здесь точно, как настроить его в Eclipse 3.5 (извините за нечетное форматирование, но это единственный способ найти отступы):

Create empty "classes" dir in plugin project
Select plugin project, hit F5 to refresh resources
Create new Ant build file in plugin project to copy dependencies (ours is shown below)

Right-click plugin project, select Properties
  Select Builders
  Click "New..." (brings up Edit Configuration dialog)
    Select Ant Builder and click "OK"
    Name your builder (ours is called "PluginProject externals")
    Browse workspace for Buildfile (ours is ${workspace_loc:/PluginProject/copyDependencies.xml})
    click Refresh tab
      check "Refresh resources upon completion", click "Specific resources"
      click "Specify Resources...", check box for the classes dir, click "Finish"
  Click "OK" (closes Edit Configuration dialog)
  Click "Up" to move "PluginProject externals" to top of builder list
Click "OK" (closes Properties dialog)

Open your plugin project MANIFEST.MF
Click "Runtime" tab
Click "Add..." under "Classpath", select your the "classes" dir and JARs and click "OK"

Ручное создание пустого каталога "classes" в проекте плагина - это значит, что вы можете сообщить вашему новому строителю об обновлении этого ресурса (который еще не существует до запуска нового застройщика). Вот что в нашем файле copyDependencies.xml:

<project name="Copy dependencies" default="copyDependencies" basedir=".">
  <!--
    This copying is needed because it appears that Eclipse plugins can't
    depend directly on external Eclipse projects.
  -->
  <description>
    Copies external dependency class andd JAR files into this plugin directory.
  </description>

  <target name="copyDependencies">
    <copy file="../External/JDOM/jdom-1.0/build/jdom.jar" todir="." preservelastmodified="true"/>
    <copy file="../External/Xalan/xalan-j_2_6_0/bin/xalan.jar" todir="." preservelastmodified="true"/>
    <copy file="../External/Xalan/xalan-j_2_6_0/bin/xercesImpl.jar" todir="." preservelastmodified="true"/>
    <copy file="../External/Xalan/xalan-j_2_6_0/bin/xml-apis.jar" todir="." preservelastmodified="true"/>
    <copy todir="./classes/com/arm" preservelastmodified="true">
      <fileset dir="../Utilities/src/com/arm" excludes="**/*.java"/>
    </copy>
  </target>
  <target name="clean" description="Deletes local copies of external classes and JARs.">
    <delete file="jdom.jar" quiet="true"/>
    <delete file="xalan.jar" quiet="true"/>
    <delete file="xercesImpl.jar" quiet="true"/>
    <delete file="xml-apis.jar" quiet="true"/>
    <delete dir="./classes/com/arm/utilities" quiet="true"/>
  </target>
</project>

Единственным недостатком этого метода, по-видимому, является то, что Eclipse не на 100% отлично справляется с вызовом внешнего построителя, когда ему нужно вызвать, поэтому иногда вам нужно выполнить "Project > Clean..." в Eclipse, чтобы закрепите его.

Ответ 4

У вас есть мои симпатии. Я тоже столкнулся с этой проблемой, и Wall-of-Silence от Eclipse разрабатывает такой простой, очевидный вопрос: как объявить зависимость от плагина к нормальному Java-проекту (например, что он работает во время выполнения)?

Я не думаю, что они поддерживают это. Единственный способ решить проблему - создать папки внутри моих проектов плагинов, которые на самом деле связаны с bin/folders java-проектов, а затем включить эти папки в плагин. Это, по крайней мере, работает, но его хрупкое из-за требуемых абсолютных путей файловой системы.

Ответ 5

возможно, вы можете использовать "свойства проекта" → "сборка развертывания" в Eclipse и добавить другие проекты в свой основной проект. Другие проекты видят как "банки", которые автоматически добавляются в ваш файл развертывания (война, ухо или что-то еще). Может быть, это могут быть работы. По крайней мере, это работает для меня. Удачи!

Ariesandes.

Ответ 6

В свойствах свойств сборки есть опция "Источник ссылок", которая позволяет вам определять дополнительные исходные папки для проекта. Вы можете выбрать папку "src" другого проекта рабочей области и переименовать ее в "src2" или что угодно. Таким образом, классы компилируются и развертываются в выходной папке проекта подключаемого модуля и могут быть загружены во время выполнения.

Ответ 7

Со сложным набором зависимостей построения я нашел Maven2 и Hudson (для CI) очень приятной комбинацией. Потребовалось время, чтобы настроить инфраструктуру и настроить конфигурацию, но после этого она просто сработала.

Конечно, вы зависите от поддержки Maven2 (или Hudson) для своего механизма сборки. Я не уверен, насколько хорошо поддерживаются сборки Eclipse Headless. Но если единственная причина, по которой вы используете Eclipse без головы, - это позволить выражениям выражаться в одном месте, сделайте себе одолжение и переключитесь.

Ответ 8

У меня такие же проблемы. У нас есть набор из нескольких нормальных java-проектов, которые могут быть созданы Maven и должны (в настоящее время) использовать один и тот же classpath для правильной работы. Эти проекты могут использоваться для запуска сервера в среде, отличной от OSGi. Затем у нас также есть клиент RCP eclipse, который использует эти проекты как один пакет. Я прекрасно могу построить этот однострочный пакет с Maven с помощью Apache Felix Maven Bundle Plugin, и все работает отлично. Но всякий раз, когда я меняю один класс в обычном проекте, мне нужно перестроить весь пакет. Инкрементная сборка и привязка ресурсов не работают.

Я попробовал "решение" со связыванием двоичных файлов/исходных каталогов из этих проектов в путь класса Manifest для одного большого пакета и, похоже, это работает, но это будет настоящий кошмар для обслуживания, потому что мне даже нужно связать некоторые отдельные файлы.

Так по иронии судьбы ПОСЛЕДСТВИЯ использования OSGi в клиенте я на самом деле думаю о сворачивании нашей красивой и модульной структуры с модулями Maven в подпакеты только одного проекта плагина. Это лучшая альтернатива, чем чрезвычайно медленное развитие.

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

(В частности, мы используем фреймворк Spring, и мы объединяем несколько файлов persistence.xml в один контекст персистентности. Мы также объединяем несколько XML-контекстных файлов Spring из разных модулей (все из которых содержат другой ASPECT), которые должны вместе формировать один Spring, который будет использоваться Spring -DM.)