2016-10-14 11 views
8

У меня есть 3 проекта следующей структуры:Apache Айви. Переходная зависимости не извлекаться

App 
| | 
    ... 
| | 
| +--lib 
| | | 
| | +--... 
| | 
| +--dist 
| 
Lib 
| | 
    ... 
| | 
| +--lib 
| | | 
| | +--sublib-1.0.jar 
| | 
| +--dist 
|  | 
|  +--lib-1.0.jar 
| 
SubLib 
    | 
    ... 
    | 
    +--dist 
     | 
     +--sublib-1.0.jar 

Которые имеют следующее соотношение:

App <-- Lib <-- SubLib 

Я использую апачский плющ для получения зависимостей для обоих App и Lib. Зависимости описываются следующим образом: ivy.xml из Lib:

<ivy-module version = "2.0"> 
    <info organisation = "com.test.lib" module = "lib"/> 
    <dependencies> 
     <dependency org = "com.test.sub.lib" name = "sublib" rev = "1.0" conf = "compile->default"/> 
    </dependencies> 
</ivy-module> 

ivy.xml из App:

<ivy-module version = "2.0"> 
    <info organisation = "com.test.app" module = "App"/> 
    <dependencies> 
     <dependency org = "com.test.lib" name = "lib" rev = "1.0" conf = "compile->default"/> 
    </dependencies> 
</ivy-module> 

ivysettings.xml:

<ivysettings> 
    <settings defaultResolver = "local"/>  
    <resolvers> 
     <filesystem name = "local"> 
      <artifact pattern = "${ivy.settings.dir}/SubLib/dist/[artifact]-[revision].[ext]"/> 
      <artifact pattern = "${ivy.settings.dir}/Lib/dist/[artifact]-[revision].[ext]"/> 
     </filesystem> 
    </resolvers>  
    <modules> 
     <module organisation = "com.test.ivytest" resolver = "local"/> 
    </modules> 
</ivysettings> 

Ожидаемый результат: после выполнения ivy:retrieve, б и др sublib-1.0.jarlib-1.0.jar присутствовать в App/lib

Фактический результат: только lib-1.0.jar присутствует в App/lib. Сгенерированный плющ-отчет для App не содержит упоминания о sublib, являющемся зависимым от lib. Ничего подобного не существует в журналах муравьев + плющ во время сборки.

Примечание:lib-1.0.jar не строится как жирная банка.

Что мне не хватает в этой конфигурации?


Update

Я сделал некоторые мысли, и единственный вывод, который я пришел с в том, что эта проблема действительно расконфигурация. Судя по тому, что транзитивная зависимость не извлекается, мы можем положительно сказать, что плющ не имеет никакой информации, когда она разрешает lib. И это имеет смысл, потому что папка Lib/dist может быть где угодно в файловой системе. Единственный способ получить информацию о транзитивной зависимости будет иметь ivy.xml где-то рядом с этой банкой. Который не. Это немного подтверждается сообщением в журналах [ivy:retrieve] local: no ivy file found for com.test.lib#lib;1.0: using default data. Единственный способ сохранения информации - данные кэша в %user%/.ivy/cache. Там сгенерированные файлы [org]-[artifact]-[conf].xml содержат информацию о зависимостях. Поэтому я предполагаю, что для правильной работы мне придется использовать кеш на уровне разрешения приложения.

Это имеет смысл, или я снова не прав?

+0

ivy: разрешить нужно вызвать до извлечения. Какие ошибки вы получаете? Есть что-то вроде «конфигурации отсутствует»? – cantSleepNow

+0

От того, что я смог понять, это не обязательно. Я вижу для разделов '[ivy: retrieve]' в журналах, что он выполняет решение. Я не получаю ошибок, это просто транзитивные jar-зависимости. – HighPredator

+1

Хорошо (читая обновленную часть также), возможно, очистите кэш плюща и запустите его снова. Также добавьте к вопросу скрипт (ы) муравей, который вы используете для публикации 'lib' и' sublib'. – cantSleepNow

ответ

0

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

Sublib собирается быть выполнения зависимость для Lib, которая имеет время компиляции зависимостей guava.

SubLib 
    | `lib 
    |  `guava-19.0.jar 
    | 
    `dist 
    | `--sublib-1.0.jar 
    | 
    `src 
     `... 

Итак, нам нужно сделать соответствующие конфигурации в ivy.xml SubLib в:

<ivy-module version="2.0"> 
    <info organisation="com.test.sub.lib" module="sublib"/> 

    <configurations> 
     <conf name="runtime" visibility="public"/> 
    </configurations> 

    <dependencies> 
     <dependency org="com.google" name="guava" rev="19.0" conf="runtime->default"/> 
    </dependencies> 
</ivy-module> 

Здесь, объявляя конфигурацию runtime мы утверждаем, что это ivy.xml описывает модуль, который является исполняемым-зависимостью от времени. И поскольку у guava нет такого файла, мы описываем его как значение по умолчанию. Здесь довольно стандартный. Теперь, для других, чтобы знать, что sublib-1.0.jar действительно имеет зависимость от guava-19.0.jar, нам нужно опубликовать его в репозитории, чтобы такая информация существовала в виде файла ivy-[version].xml рядом с банкой. Я решил опубликовать в папке build. Для этого ivysettings.xml должен содержать средство распознавания, которое помогает сопоставлять шаблоны файлов для публикации, а затем при поиске, когда мы разрешим его с Lib.

<ivysettings> 
    <settings defaultResolver="filesystem-resolver"/> 

    <resolvers> 
     <filesystem name="sublib-resolver"> 
      <ivy pattern="${ivy.settings.dir}/SubLib/dist/repo/ivy-[revision].xml"/> 
      <artifact pattern="${ivy.settings.dir}/SubLib/dist/repo/[artifact]-[revision].[ext]"/> 
     </filesystem> 

     <filesystem name="filesystem-resolver"> 
      <artifact pattern="${ivy.settings.dir}/SubLib/lib/[artifact]-[revision].[ext]"/> 
     </filesystem> 
    </resolvers> 

    <modules> 
     <module name="sublib" organisation="com.test.sub.lib" resolver="sublib-resolver"/> 
    </modules> 
</ivysettings> 

sublib-resolver позволит найти соответствующий ivy-[revision].xml, что имеет информацию о зависимостях и местоположении jar. В то время как filesystem-resolver найдет нашу зависимость guava. Теперь мы просто опубликовать sublib с ant, вызывая наш распознаватель:

<target name="publish"> 
     <ivy:publish artifactspattern="${dist.dir}/[artifact]-[revision].[ext]" 
        resolver="sublib-resolver" 
        overwrite="true" 
        pubrevision="${revision}" 
     /> 
</target> 

Теперь Lib. Lib собирается быть времени компиляции зависимости для App и мы опишем его как таковые в ivy.xml и объявить SubLib в выполнении зависимости в для него:

<ivy-module version="2.0"> 
    <info organisation="com.test.lib" module="lib"/> 

    <configurations> 
     <conf name="compile" visibility="public"/> 
     <conf name="runtime" extends="compile" visibility="public"/> 
    </configurations> 

    <dependencies> 
     <dependency org="com.test.sub.lib" name="sublib" rev="2.0" conf="runtime->compile"/> 
    </dependencies> 
</ivy-module> 

Вот где конфигурация приходит в игре, и то, что я сначала не понял. runtime->compile Левая сторона понятна: sublib был объявлен как зависимость от времени выполнения, и мы назначили его runtime conf в его плющ-файл. С правой стороны стрелки укажем, что мы хотим также использовать зависимости времени компиляции sublib. И тот, который был настроен как таковой, - guava. Он будет найден и распознавателем. Таким образом, нам нужно распознаватель для Lib, так что полный ivysettings.xml файл будет выглядеть следующим образом:

<ivysettings> 
    <properties file="${ivy.settings.dir}/ivysettings.properties"/> 

    <settings defaultResolver="filesystem-resolver"/> 

    <resolvers> 
     <filesystem name="sublib-resolver"> 
      <ivy pattern="${ivy.settings.dir}/SubLib/dist/repo/ivy-[revision].xml"/> 
      <artifact pattern="${ivy.settings.dir}/SubLib/dist/repo/[artifact]-[revision].[ext]"/> 
     </filesystem> 

     <filesystem name="lib-resolver"> 
      <ivy pattern="${ivy.settings.dir}/Lib/dist/repo/ivy-[revision].xml"/> 
      <artifact pattern="${ivy.settings.dir}/Lib/dist/repo/[artifact]-[revision].[ext]"/> 
     </filesystem> 

     <filesystem name="filesystem-resolver"> 
      <artifact pattern="${ivy.settings.dir}/SubLib/lib/[artifact]-[revision].[ext]"/> 
     </filesystem> 
    </resolvers> 

    <modules> 
     <module name="sublib" organisation="com.test.sub.lib" resolver="sublib-resolver"/> 
     <module name="lib" organisation="com.test.lib" resolver="lib-resolver"/> 
    </modules> 
</ivysettings> 

И опубликовать из Lib в Lib «s build.xml:

<target name="publish"> 
     <ivy:publish artifactspattern="${dist.dir}/[artifact]-[revision].[ext]" 
        resolver="lib-resolver" 
        overwrite="true" 
        pubrevision="${revision}" 
     /> 
</target> 

Теперь к главной проблеме: переходный поиск. Конфигурации. В ivy.xml нам нужно точно указать, что мы хотим транзитивных зависимостей. Информация, которую они хранят в репозиториях, недостаточно.Необходимо указать его в App «s ivy.xml:

<configurations> 
    <conf name="compile" visibility="public"/> 
</configurations> 

<dependencies> 
    <dependency org="com.test.lib" name="lib" rev="1.0" conf="compile->compile; compile->runtime"/> 
</dependencies> 

Что здесь происходит следующее: объявляя compile конф мы утверждаем, что App имеет конфигурацию компиляции. Первая цепочка стрелок, как и раньше, заявляет, что мы (модуль с настройкой компиляции App) хотим получить зависимую от компиляции зависимость, называемую lib. Левая и правая стрелки соответственно. И вторая стрелка устанавливает, что мы (компилируемый модуль App) хотим получить зависящие от времени зависимости от lib! Который sublib. И поскольку он приходит вместе с guava, он также извлекается.


Немного грязный объяснение, и может очень не быть самой элегантной один для solutioin, но это единственный способ, мне удалось сделать эту работу должным образом на всех. Если кто-нибудь знает какие-либо лучшие способы сделать это, любая помощь будет оценена по достоинству.