Maven: dodaj zależność do słoika według ścieżki względnej

232

Mam zastrzeżony słoik, który chcę dodać do mojej pom jako zależność.

Ale nie chcę dodawać go do repozytorium. Powodem jest to, że chcę, aby moje zwykłe polecenia, takie jak mvn compileitp., Działały od razu po wyjęciu z pudełka. (Bez wymagania od programistów dodania go do własnego repozytorium).

Chcę, aby słoik znajdował się w bibliotece stron trzecich pod kontrolą źródła, i link do niego poprzez względną ścieżkę z pliku pom.xml.

Czy można to zrobić? W jaki sposób?

Lecieć jak po sznurku
źródło

Odpowiedzi:

343

Chcę, aby słoik znajdował się w bibliotece stron trzecich pod kontrolą źródła, i link do niego poprzez względną ścieżkę z pliku pom.xml.

Jeśli naprawdę tego chcesz (rozumiesz, jeśli nie możesz korzystać z repozytorium korporacyjnego), to radzę użyć lokalnego repozytorium plików dla projektu i nie używaćsystem zależności o zasięgu. systemNależy unikać zakresu, takie zależności nie działają dobrze w wielu sytuacjach (np. Podczas montażu), powodują więcej problemów niż korzyści.

Zamiast tego zadeklaruj repozytorium jako lokalne dla projektu:

<repositories>
  <repository>
    <id>my-local-repo</id>
    <url>file://${project.basedir}/my-repo</url>
  </repository>
</repositories>

Zainstalować trzeciej partii lib tam korzystając install:install-filez localRepositoryPathparametru:

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<myGroup> \ 
                         -DartifactId=<myArtifactId> -Dversion=<myVersion> \
                         -Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

Aktualizacja: Wygląda na to, że install:install-fileignoruje localRepositoryPathużycie wtyczki w wersji 2.2. Działa jednak z wersją 2.3 i późniejszymi wtyczek. Więc użyj w pełni kwalifikowanej nazwy wtyczki, aby określić wersję:

mvn org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file \
                         -Dfile=<path-to-file> -DgroupId=<myGroup> \ 
                         -DartifactId=<myArtifactId> -Dversion=<myVersion> \
                         -Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

Dokumentacja maven-install-plugin

Na koniec zadeklaruj to jak każdą inną zależność (ale bez systemzakresu):

<dependency>
  <groupId>your.group.id</groupId>
  <artifactId>3rdparty</artifactId>
  <version>X.Y.Z</version>
</dependency>

Jest to IMHO lepsze rozwiązanie niż korzystanie z systemzakresu, ponieważ twoja zależność będzie traktowana jak dobry obywatel (np. Zostanie uwzględniona w zgromadzeniu i tak dalej).

Teraz muszę wspomnieć, że „właściwym sposobem” radzenia sobie z tą sytuacją w środowisku korporacyjnym (być może nie w tym przypadku) byłoby skorzystanie z repozytorium korporacyjnego.

Pascal Thivent
źródło
2
To świetny pomysł, ale w Maven 2.2.1 wtyczka instalacyjna wydaje się ignorować localRepositoryPath...
Jake
1
Po co deklarować lokalne repozytorium? Dlaczego nie po prostu pozwolić mu przejść do ~ / .m2 / wraz z resztą.
Leif Gruenwoldt,
6
@ leif81 Ponieważ wtedy repozytorium i biblioteki są sprawdzane w repozytorium SCM -> Każdy, kto dokonuje pobrania źródła, ma wszystko, czego potrzeba, aby zbudować kopię biblioteki / aplikacji.
Darth Android
6
Miałem ten sam problem co @lemon, który rozwiązałem, wykonując basedir/./my-local-repojeden ..
Brian
2
Opakowanie musi być słoikiem, dlatego -Dopakowanie = słoik
Danila Piatov
127

Korzystanie z systemzakresu. ${basedir}to katalog twojej pom.

<dependency>
    <artifactId>..</artifactId>
    <groupId>..</groupId>
    <scope>system</scope>
    <systemPath>${basedir}/lib/dependency.jar</systemPath>
</dependency>

Jednak wskazane jest, aby zainstalować słoik w repozytorium, a nie zatwierdzać go w SCM - w końcu to właśnie próbuje wyeliminować maven.

Bozho
źródło
15
System zakresu należy unikać wszędzie tam, gdzie jest to możliwe. Zainstalowanie JAR w repozytorium jest lepszym rozwiązaniem ...
Gandalf StormCrow
14
tak, jeśli to możliwe. powiedział wyraźnie, że nie chce go umieścić w repozytorium. Dodałem komentarz, aby podkreślić, że nie jest to dobra praktyka. Ale to działa.
Bozho
groovy, wydaje mi się, że jak dotąd najbardziej akceptowalne jest rozwiązanie. Całkowicie źle odczytałem pytanie
mrówka
Tak - samo pytanie wyklucza najlepszą odpowiedź. Umieszczenie wszystkiego w jednym serwerze kontroli źródła nie ma wiele wspólnego z „budowaniem po wyjęciu z pudełka”; raczej wszystko musi być „kontrolowane”. Wykonaj odprawę pom & settings.xml (wskazując na wewnętrzne repozytorium) i użyj dwóch serwerów dla swojego projektu: (1) kontrola źródła, (2) wygenerowana kontrola artefaktów. Sprawdzanie w słoikach ma tyle samo sensu, co sprawdzanie w bibliotekach dll (moja stara korporacja faktycznie robiła słoiki i biblioteki lib.a / .so / .dll. Nasz serwer p4 był tak wolny później, niektórzy potajemnie używali hg na dzień - codzienna praca. Problem rozwiązany?
Michael
w jakikolwiek sposób określić katalog zawierający słoiki, więc nie musimy dodawać każdego z nich, tak jak gradle może to zrobić?
Dean Hiller
29

To jest inna metoda oprócz mojej poprzedniej odpowiedzi: Czy mogę dodawać słoiki do ścieżki klas maven 2 bez ich instalowania?

Obejdzie to limit podczas korzystania z kompilacji wielomodułowych, zwłaszcza jeśli do pobranego pliku JAR odwołuje się projekt potomny. Zmniejsza to również prace instalacyjne, tworząc pliki POM i SHA1 jako część kompilacji. Pozwala także na umieszczenie pliku w dowolnym miejscu w projekcie bez ustalania nazw lub śledzenia struktury repozytorium maven.

To używa wtyczki maven-install-plug. Aby to zadziałało, musisz skonfigurować projekt wielomodułowy i mieć nowy projekt reprezentujący kompilację, aby zainstalować pliki w lokalnym repozytorium i upewnić się, że jest on pierwszy.

Twój wielomodułowy projekt pom.xml wyglądałby tak:

<packaging>pom</packaging>
<modules>
<!-- The repository module must be first in order to ensure
     that the local repository is populated -->
    <module>repository</module>
    <module>... other modules ...</module>
</modules>

Plik repository / pom.xml będzie zawierał definicje ładowania plików JAR, które są częścią projektu. Oto niektóre fragmenty pliku pom.xml.

<artifactId>repository</artifactId>
<packaging>pom</packaging>

Opakowanie pom zapobiega wykonywaniu jakichkolwiek testów, kompilacji lub generowaniu plików jar. Mięso pom.xml znajduje się w sekcji kompilacji, w której jest używana wtyczka maven-install-plugin.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <executions>
                <execution>
                        <id>com.ibm.db2:db2jcc</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>install-file</goal>
                        </goals>
                        <configuration>
                            <groupId>com.ibm.db2</groupId>
                            <artifactId>db2jcc</artifactId>
                            <version>9.0.0</version>
                            <packaging>jar</packaging>
                            <file>${basedir}/src/jars/db2jcc.jar</file>
                            <createChecksum>true</createChecksum>
                            <generatePom>true</generatePom>
                        </configuration>
                </execution>
                <execution>...</execution>
            </executions>
        </plugin>
    </plugins>
</build>

Aby zainstalować więcej niż jeden plik, wystarczy dodać więcej wykonań.

Archimedes Trajano
źródło
To jedyna rzecz, która zadziałała w moim projekcie złożonym z wielu modułów. Lokalne podejście <repository> z nieznanego powodu nie działało. Więc dziękuję!
Lonzak,
10

To działa dla mnie: powiedzmy, że mam tę zależność

<dependency>
    <groupId>com.company.app</groupId>
    <artifactId>my-library</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/my-library.jar</systemPath>
</dependency>

Następnie ręcznie dodaj ścieżkę klasy dla zależności systemowej w ten sposób

<Class-Path>libs/my-library-1.0.jar</Class-Path>

Pełna konfiguracja:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifestEntries>
                <Build-Jdk>${jdk.version}</Build-Jdk>
                <Implementation-Title>${project.name}</Implementation-Title>
                <Implementation-Version>${project.version}</Implementation-Version>
                <Specification-Title>${project.name} Library</Specification-Title>
                <Specification-Version>${project.version}</Specification-Version>
                <Class-Path>libs/my-library-1.0.jar</Class-Path>
            </manifestEntries>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>com.company.app.MainClass</mainClass>
                <classpathPrefix>libs/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.5.1</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/libs/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
RufusSC2
źródło
9

Wcześniej pisałem o tym, jak to zrobić.

Jest bardzo podobny do rozwiązania zaproponowanego przez Pascala, chociaż przenosi wszystkie takie zależności do dedykowanego modułu repozytorium, dzięki czemu nie trzeba go powtarzać wszędzie, zależność jest używana, jeśli jest to kompilacja wielomodułowa.

Brett Porter
źródło
6

Zasadniczo dodaj to do pliku pom.xml:

...

<repositories>
   <repository>
       <id>lib_id</id>
       <url>file://${project.basedir}/lib</url>
   </repository>
</repositories>

...

<dependencies>
  ...
  <dependency>
      <groupId>com.mylibrary</groupId>
      <artifactId>mylibraryname</artifactId>
      <version>1.0.0</version>
  </dependency>
  ...
</dependencies>
Fulgencio Jara
źródło
4

przeszliśmy na gradle i działa to znacznie lepiej na grad;). po prostu określamy folder, do którego możemy upuścić słoiki w takich tymczasowych sytuacjach. Wciąż mamy większość naszych słoików zdefiniowanych w typowej sekcji zarządzania zależnościami (tj. Takiej samej jak maven). To tylko jedna zależność, którą definiujemy.

więc w zasadzie teraz możemy po prostu wrzucić dowolny słoik do katalogu lib do tymczasowego testowania, jeśli nie jest to gdzieś repozytorium.

Dean Hiller
źródło
1
Czy możesz podać przykład, jak to zrobiłeś?
Thomas
2

Jeden mały dodatek do rozwiązania opublikowanego przez Pascala

Gdy podążyłem tą drogą, podczas instalowania jar jardbc wystąpił błąd w maven.

[INFO] --- maven-install-plugin:2.5.1:install-file (default-cli) @ validator ---
[INFO] pom.xml not found in ojdbc14.jar

Po dodaniu opcji -DpomFile problem został rozwiązany.

$ mvn install:install-file -Dfile=./lib/ojdbc14.jar -DgroupId=ojdbc \
   -DartifactId=ojdbc -Dversion=14 -Dpackaging=jar -DlocalRepositoryPath=./repo \
   -DpomFile=~/.m2/repository/ojdbc/ojdbc/14/ojdbc-14.pom
veeseekay
źródło
0

Za pomocą Eclipse można wygenerować uruchamialny plik Jar: Export / Runable Jar

użytkownik1942990
źródło
Nie jestem pewien, czy to odpowiada na pytanie. Ma już plik jako słoik.
Johannes Jander
Eclipse obsługuje uberjar lub zacieniony słoik, więc jest to rozwiązanie, ale nie dla maven
Alex Lehmann