2016-10-14 13 views
8

Mam 3 projekty o następującej strukturze:Apache Ivy. Przechodnia nie Zależności pobierane

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

Które mają następującą zależność:

App <-- Lib <-- SubLib 

używam apache bluszcz odzyskać zależności zarówno App i Lib. Zależności te są opisane w następujący sposób: ivy.xml z 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 z 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> 

Oczekiwany wynik: po wykonaniu ivy:retrieve b oth sublib-1.0.jar i lib-1.0.jar być obecny w App/lib

Rzeczywisty rezultat: tylko lib-1.0.jar jest obecny w App/lib. Wygenerowany raport ivy dla App nie zawiera żadnej wzmianki o sublib będącym zależnością od lib. Nic nie ma też w logach mrówek + bluszcz podczas kompilacji.

Uwaga:lib-1.0.jar nie jest budowany jako słoik.

Czego mi brakuje w tej konfiguracji?


Aktualizacja

Zrobiłem trochę myślenia, a jedynie wniosek przyjechałem z jest to, że ten problem jest rzeczywiście błąd konfiguracji. Sądząc po tym, że zależność przechodnia nie jest pobierana, możemy pozytywnie powiedzieć, że bluszcz nie posiada żadnych informacji, gdy rozstrzyga lib. I to ma sens, ponieważ folder Lib/dist może znajdować się w dowolnym miejscu w systemie plików. Jedynym sposobem uzyskania informacji na temat zależności przechodniów byłaby odpowiednia lokalizacja w pobliżu tego słoika. Który nie jest. Jest to nieco potwierdzone przez komunikat w dziennikach [ivy:retrieve] local: no ivy file found for com.test.lib#lib;1.0: using default data. Jedynym sposobem przechowywania tych informacji są dane z pamięci podręcznej w %user%/.ivy/cache. Tam wygenerowane pliki [org]-[artifact]-[conf].xml zawierają informacje o zależnościach. Zgaduję więc, że to działa poprawnie, będę musiał użyć pamięci podręcznej na poziomie rozdzielczości aplikacji.

Czy to ma jakiś sens, czy ja znowu mam rację?

+0

Bluszcz: postanowienie powinno zostać wywołane przed odzyskaniem. Jakie są błędy, które otrzymujesz? CZY istnieje coś takiego jak "brakująca konfiguracja"? – cantSleepNow

+0

Z tego, co udało mi się zrozumieć, wynika, że ​​nie jest to konieczne. Widzę dla sekcji '[ivy: retrieve]' w dziennikach, że wykonuje rozstrzygnięcie. Nie dostaję żadnych błędów, to tylko przejściowe zależności słoiczków. – HighPredator

+1

Ok (czytanie zaktualizowanej części również) może proszę wyczyścić pamięć podręczną bluszcza i uruchomić ją ponownie. Dodaj również do pytania skrypt (y) mrówki, których używasz do publikowania 'lib' i' sublib'. – cantSleepNow

Odpowiedz

0

Ok, więc problem był w rzeczywistości zły konfiguracji i mój brak zrozumienia go. Oto szczegółowe wyjaśnienie, jak to zrobić. Nie jestem zbyt dobry w terminologii, więc mogłem nadużywać niektórych słów tutaj. Spójrzmy na konfigurację projektu i co tam.

Sublib ma być Runtime zależność dla Libktóry ma czasu kompilacji zależnościach guava.

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

Tak, musimy wprowadzić odpowiednie konfiguracje w SubLib za ivy.xml:

<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> 

Tutaj deklarując konfigurację runtime stwierdzić, że ten ivy.xml opisuje moduł, który jest zależnością runtime-czas. A ponieważ guava nie ma takiego pliku, opisujemy go jako domyślny. Całkiem standardowe tutaj. Teraz, aby inni wiedzieli, że sublib-1.0.jar rzeczywiście ma zależność od guava-19.0.jar musimy opublikować go do repozytorium, tak aby takie informacje istniały w formie pliku ivy-[version].xml obok słoika. Zdecydowałem się opublikować w folderze build. Aby to zrobić, ivysettings.xml musi zawierać resolver, który pomaga dopasować wzorce plików do opublikowania, a później do pobierania, gdy rozwiążemy ten problem od 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 pozwoli na znalezienie odpowiedniego ivy-[revision].xml że ma informacje o zależnościach i lokalizacji jar. Natomiast filesystem-resolver znajdzie naszą zależność guava. Teraz po prostu opublikować sublib z ant powołując naszą resolverowi:

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

teraz do Lib. Lib ma być kompilacji zależność dla App i opiszemy je jako takie w ivy.xml i deklarują SubLib jako zależność wykonawczego do niego:

<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> 

Oto gdzie konfiguracja jest w grze i co ja początkowo nie rozumiałem. runtime->compile Strona lewa jest zrozumiała: sublib została zadeklarowana jako zależność runtime i przypisaliśmy ją do runtime conf w jej pliku bluszczu. Po prawej stronie strzałki informujemy, że chcemy również zależności w czasie kompilacji sublib. Ten skonfigurowany jako taki to guava. Zostanie on znaleziony przez resolver i odzyskany. Więc musimy rozpoznawania nazw dla Lib, tak więc pełna ivysettings.xml plik będzie wyglądać następująco:

<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> 

i publikuje od Lib w Lib „s build.xml:

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

teraz do głównego problemu: przechodnie. Konfiguracje. W App 's musimy podać dokładnie to, co chcemy przechować zależności. Informacje, że istnieją, przechowywane w repozytoriach, nie wystarczą.Trzeba określić ją w 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> 

Co się dzieje tutaj jest następujący: deklarując compile conf stwierdzić, że App ma konfigurację kompilacji. Pierwszy łańcuch strzałki, jak poprzednio, stwierdza, że ​​(skompilowany w konfiguracji moduł App) chcemy uzyskać zależność skonfigurowaną w trybie kompilacji o nazwie lib. Lewa i prawa strona strzałek odpowiednio. Drugi zestaw strzałek stwierdza, że ​​(skompilowaliśmy moduł App) chcemy uzyskać skonfigurowane w trybie runtime zależności od lib! Który jest sublib. A ponieważ przychodzi razem z guava, jest również pobierany.


Trochę niechlujny wyjaśnienie, a nie może być bardzo najbardziej elegancki jeden na solutioin, ale to jedyny sposób udało mi się do tej pracy właściwie w ogóle. Jeśli ktokolwiek wie, jak to zrobić, to każda pomoc będzie doceniona.

Powiązane problemy