Maven: najlepszy sposób na połączenie niestandardowego zewnętrznego pliku JAR z moim projektem?

151

To moje pierwsze dni nauki Mavena i wciąż zmagam się z podstawami. Mam zewnętrzny plik .jar (niedostępny w publicznych repozytoriach), do którego muszę się odwoływać w moim projekcie i próbuję dowiedzieć się, jaka jest moja najlepsza opcja.

Jest to projekt na małą skalę bez centralnego repozytorium dla bibliotek, więc musi to być repozytorium lokalne (w jakiś sposób dodane do kontroli źródła, nie wiem, czy ma to działać w ten sposób?) Lub plik .jar musi być przechowywany na dysk poza jakimkolwiek formalnym repozytorium.

1) Jaka jest najlepsza opcja dodawania pliku .jar do odwołań mojego projektu za pomocą maven, biorąc pod uwagę, że chcę, aby zarówno projekt, jak i biblioteka znajdowały się w kontroli źródła?

2) Nadal nie wydaje mi się, aby Eclipse widział zależność. Dodałem go ręcznie do sekcji pom i jest dobrze widoczny na liście zależności w m2eclipse. Kompilacja mvn i pakiet mvn powiodły się, ale uruchomienie programu skutkuje:

Exception in thread "main" java.lang.Error: Unresolved compilation problems:
        LibraryStuff cannot be resolved to a type

To jest po edycji POM jako:

<dependency>
  <groupId>stuff</groupId>
  <artifactId>library</artifactId>
  <version>1.0</version>
  <systemPath>${lib.location}/MyLibrary.jar</systemPath>
  <scope>system</scope>
</dependency>

Czy powinienem wykonać instalację mvn: plik instalacyjny, nawet myślałem, że mam już plik pom.xml edytowany jak powyżej?

Dzięki!

Alexandr Kurilin
źródło

Odpowiedzi:

67

Myślę, że powinieneś użyć mvn install:install-filedo zapełnienia lokalnego repozytorium słojami biblioteki, a następnie powinieneś zmienić zakres z systemu na kompilację.

Jeśli zaczynasz od mavena, sugeruję użycie wtyczek maven bezpośrednio, a nie wtyczek IDE, ponieważ dodaje to dodatkową warstwę złożoności.

Co do błędu, czy umieszczasz wymagane słoiki na ścieżce klas? Jeśli używasz typów z biblioteki, musisz mieć do nich dostęp również w środowisku wykonawczym. To nie ma nic wspólnego z samym mavenem.

Nie rozumiem, dlaczego chcesz umieścić bibliotekę pod kontrolą źródła - jest to kod źródłowy, a nie binarny jars.

prześladowca
źródło
36
więcej na mvn install::install-file: mkyong.com/maven/…
Doug T.
7
Używanie mvn install::install-filew lokalnym repozytorium oznaczałoby, że każdy, kto klonuje twój kod źródłowy, musiałby również wykonać ten ręczny krok. W przeciwnym razie kompilacja jest zepsuta po wyjęciu z pudełka
Isen Ng
to jednak nie doda jar do pliku wojennego.
Prachi,
207

Możesz utworzyć repozytorium w projekcie, więc nie musisz tego robić za run mvn install:install-filekażdym razem, gdy pracujesz na nowym komputerze

<repository>
    <id>in-project</id>
    <name>In Project Repo</name>
    <url>file://${project.basedir}/libs</url>
</repository>

<dependency>
    <groupId>dropbox</groupId>
    <artifactId>dropbox-sdk</artifactId>
    <version>1.3.1</version>
</dependency>

/groupId/artifactId/version/artifactId-verion.jar

szczegółowo przeczytaj ten post na blogu

https://web.archive.org/web/20121026021311/charlie.cu.cc/2012/06/how-add-external-libraries-maven

Charlie Wu
źródło
2
Użycie powyższego rozwiązania pokazało ostrzeżenie podczas wykonywania "czystego pakietu mvn" - Brakuje POM dla projektu <nazwa_zależności>, brak dostępnych informacji o zależnościach.
Jignesh Gohel
To najlepsze rozwiązanie w przypadkach, gdy musisz dodać jeden lub kilka plików jar. Dzięki.
Antonio Sesto
2
Lub możesz dodać lokalne zależności bezpośrednio, jak na stackoverflow.com/a/22300875/640378
mauryat
2
Musiałem użyć file: /// $ {project.basedir} / libs (3 przekierowane ukośniki) zamiast file: // $ {project.basedir} / libs
Loc Phan
2
Jeśli instalowany jar nie jest skompilowanym przez Mavena jar, będziesz musiał również dodać nowy plik pom, aby zdefiniować metadane. Aby zaoszczędzić sobie wszystkich tych ręcznych problemów, zalecałbym użycie, mvn install:install-filea następnie skopiowanie całej struktury katalogów z lokalnego repozytorium do repozytorium w projekcie.
Isen Ng
33

Można to łatwo osiągnąć, używając elementu <scope> zagnieżdżonego wewnątrz elementu <dependency>.

Na przykład:

 <dependencies>
   <dependency>
     <groupId>ldapjdk</groupId>
     <artifactId>ldapjdk</artifactId>
     <scope>system</scope>
     <version>1.0</version>
     <systemPath>${basedir}\src\lib\ldapjdk.jar</systemPath>
   </dependency>
 </dependencies>

Źródła: http://www.tutorialspoint.com/maven/maven_external_dependencies.htm

Jignesh Gohel
źródło
Ta metoda działa bardzo dobrze, gdy masz tylko Eclipse Embedded Maven i brakuje ci wtyczki instalacyjnej (system offline), więc nie możesz uruchomić installcelu w zależnym projekcie. Często posiadanie systemu z przerwami powietrznymi i posiadanie wszystkich wtyczek oprócz wtyczki instalacyjnej jest dość rzadką sytuacją.
Cardin Lee JH
1
Najczystsze i najłatwiejsze.
Ajay Kumar
jak dodać lokalną ścieżkę zależności, która znajduje się poza folderem $ {project.basedir}, na przykład chcę, aby ścieżka $ {basedir} \ src \ lib \ ldapjdk.jar była 1 poziom wyżej w innym folderze
Naveen Kumar
"The POM for … is missing, no dependency information available” even though it exists in Maven Repository
Pojawia
28

Podręcznik Maven mówi, aby zrobić to:

mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar
Vladislav Rastrusny
źródło
4
to polecenie zainstaluj bibliotekę w repozytorium maven. Wadą tego jest to, że jeśli próbujesz pracować nad projektem na innym komputerze, musisz uruchomić to ponownie.
Charlie Wu
25

aktualizacja Od tego czasu właśnie zainstalowaliśmy nasz własny serwer Nexus, znacznie łatwiejszy i czystszy.

W naszej firmie mieliśmy kilka słoików, które były powszechne, ale nie były hostowane w żadnym repozytorium maven, ani nie chcieliśmy mieć ich w lokalnym magazynie. Stworzyliśmy bardzo proste repozytorium mvn (publiczne) na Github (ale możesz je hostować na dowolnym serwerze lub lokalnie):
pamiętaj, że jest to idealne tylko do zarządzania kilkoma rzadko zmienianymi plikami jar

  1. Utwórz repozytorium na GitHub:
    https://github.com/<user_name>/mvn-repo/

  2. Dodaj repozytorium w pom.xml
    (zwróć uwagę, że plik raw z pełną ścieżką będzie nieco inny niż nazwa repozytorium)

    <repository>
        <id>project-common</id>
        <name>Project Common</name>
        <url>https://github.com/<user_name>/mvn-repo/raw/master/</url>
    </repository>
  3. Dodaj zależność do hosta (Github lub serwer prywatny)
    a. Wszystko, co musisz wiedzieć, to że pliki są przechowywane we wzorcu wspomnianym przez @glitch
    /groupId/artifactId/version/artifactId-version.jar
    b. Na swoim hoście utwórz foldery pasujące do tego wzorca.
    tzn. jeśli masz plik jar o nazwie service-sdk-0.0.1.jar, utwórz folder service-sdk/service-sdk/0.0.1/i umieść w nim plik jar service-sdk-0.0.1.jar.
    do. Przetestuj, próbując pobrać jar z przeglądarki (w naszym przypadku:https://github.com/<user_name>/mvn-repo/raw/master/service-sdk/service-sdk/0.0.1/service-sdk-0.0.1.jar

  4. Dodaj zależność do pliku pom.xml:

    <dependency>
        <groupId>service-sdk</groupId>
        <artifactId>service-sdk</artifactId>
        <version>0.0.1</version>
    </dependency>
  5. Cieszyć się

Kenny Cason
źródło
fajnie, to najbardziej skalowalne rozwiązanie, jakie znalazłem, dzięki
Charlie Wu
11

Nie używaj systemPath. W przeciwieństwie do tego, co ludzie tutaj powiedzieli, możesz umieścić zewnętrzny jar w folderze w wyewidencjonowanym katalogu projektu i Maven nie znajdzie go tak, jak inne zależności. Oto dwa kluczowe kroki:

  1. Użyj opcji „mvn install: install-file” z -DlocalRepositoryPath.
  2. Skonfiguruj repozytorium, aby wskazywało tę ścieżkę w twoim POM.

Jest to dość proste, a przykład krok po kroku można znaleźć tutaj: http://randomizedsort.blogspot.com/2011/10/configuring-maven-to-use-local-library.html

Nehc
źródło
8

Maven sposób na dodanie słoików innych niż Maven do projektu Maven

Maven Project i non maven słoiki

Dodaj wtyczki do instalacji maven w sekcji kompilacji

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-install-plugin</artifactId>
        <version>${version.maven-install-plugin}</version>
        <executions>

            <execution>
                <id>install-external-non-maven1-jar</id>
                <phase>clean</phase>
                <configuration>
                    <repositoryLayout>default</repositoryLayout>
                    <groupId>jar1.group</groupId>
                    <artifactId>non-maven1</artifactId>
                    <version>${version.non-maven1}</version>
                    <file>${project.basedir}/libs/non-maven1.jar</file>
                    <packaging>jar</packaging>
                    <generatePom>true</generatePom>
                </configuration>
                <goals>
                    <goal>install-file</goal>
                </goals>
            </execution>
            <execution>
                <id>install-external-non-maven2-jar</id>
                <phase>clean</phase>
                <configuration>
                    <repositoryLayout>default</repositoryLayout>
                    <groupId>jar2.group</groupId>
                    <artifactId>non-maven2</artifactId>
                    <version>${version.non-maven2}</version>
                    <file>${project.basedir}/libs/non-maven2.jar</file>
                    <packaging>jar</packaging>
                    <generatePom>true</generatePom>
                </configuration>
                <goals>
                    <goal>install-file</goal>
                </goals>
            </execution>
            <execution>
                <id>install-external-non-maven3-jar</id>
                <phase>clean</phase>
                <configuration>
                    <repositoryLayout>default</repositoryLayout>
                    <groupId>jar3.group</groupId>
                    <artifactId>non-maven3</artifactId>
                    <version>${version.non-maven3}</version>
                    <file>${project.basedir}/libs/non-maven3.jar</file>
                    <packaging>jar</packaging>
                    <generatePom>true</generatePom>
                </configuration>
                <goals>
                    <goal>install-file</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

Dodaj zależność

<dependencies>
    <dependency>
        <groupId>jar1.group</groupId>
        <artifactId>non-maven1</artifactId>
        <version>${version.non-maven1}</version>
    </dependency>
    <dependency>
        <groupId>jar2.group</groupId>
        <artifactId>non-maven2</artifactId>
        <version>${version.non-maven2}</version>
    </dependency>
    <dependency>
        <groupId>jar3.group</groupId>
        <artifactId>non-maven3</artifactId>
        <version>${version.non-maven3}</version>
    </dependency>
</dependencies>

Referencje Uwaga Jestem właścicielem bloga

craftmannadeem
źródło
Skąd znasz wersje jars i wtyczki instalacyjnej maven?
osk
wersje słoików są właśnie gotowe, wersje wtyczek Maven install są najnowsze
craftmannadeem
7

Jeśli napotkasz ten sam problem i używasz spring-boot v1.4 + , możesz to zrobić w ten sposób.

Istnieje includeSystemScope , którego można użyć do dodania zależności zakresu systemu do pliku jar.

na przykład

W moim projekcie używam sterownika Oracle.

<dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc14</artifactId>
        <version>10.2.0.3.0</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/src/main/resources/extra-jars/ojdbc14-10.2.0.3.0.jar</systemPath>
    </dependency>

następnie wykonaj includeSystemScope = true, aby dołączyć plik jar do ścieżki / BOOT-INF / lib / **

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <includeSystemScope>true</includeSystemScope>
    </configuration>
</plugin>

i wykluczyć z zasobów, aby uniknąć powielania, słoik jest wystarczająco gruby ~

<build>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>**/*.jar</exclude>
            </excludes>
        </resource>
    </resources>
</build>

Powodzenia!

chendu
źródło
Szukałem takiego rozwiązania, po prostu dlatego, że gdy pojawia się nowy programista, upraszcza to procedurę instalacji. Gdy nie masz serwera artefaktycznego, łatwiej jest mieć niestandardową zależność w projekcie. Również w przypadku korzystania z CI można uniknąć ręcznego instalowania jar na serwerze CI.
Dalc
Co powiesz na wiele słoików?
mithun_ghose
4

Zmień ścieżkę systemową .

<dependency>
  <groupId>stuff</groupId>
  <artifactId>library</artifactId>
  <version>1.0</version>
  <systemPath>${project.basedir}/MyLibrary.jar</systemPath>
  <scope>system</scope>
</dependency>
Aung Myat Hein
źródło
3

Pom.xml zajrzy do lokalnego repozytorium, aby spróbować znaleźć zależność, która pasuje do twojego artefaktu. Nie powinieneś także używać atrybutów zakresu systemowego ani atrybutów systemPath, są one zwykle zarezerwowane dla elementów znajdujących się w JDK, a nie JRE

Zobacz to pytanie, aby dowiedzieć się, jak zainstalować artefakty Mavena.

Tim Sparg
źródło
3

Zwróć uwagę, że wszystkie przykłady używają

<repository>...</respository> 

wymagają zewnętrznego

<repositories>...</repositories> 

otaczające tagi. Z niektórych przykładów nie wynika jasno.


źródło
2

Najlepszym rozwiązaniem jest tutaj instalacja repozytorium: Nexus lub Artifactory. Jeśli daje ci miejsce do umieszczania takich rzeczy, a ponadto przyspiesza to, buforując twoje rzeczy z zewnątrz.

Jeśli masz do czynienia z oprogramowaniem typu open source, możesz również rozważyć umieszczenie go w pliku centralnym.

Zobacz przewodnik .

bmargulies
źródło
1

Z Eclipse Oxygen możesz wykonać następujące czynności:

  1. Umieść swoje biblioteki w WEB-INF / lib
  2. Projekt -> Konfiguruj ścieżkę kompilacji -> Dodaj bibliotekę -> Biblioteka aplikacji sieci Web

Maven weźmie je podczas instalacji projektu.

Stóg
źródło
3
Jeśli tak, czy inni użytkownicy, którzy ściągają mój projekt, muszą robić to samo w Eclipse?
cruxi,
0

Jeśli zewnętrzny plik jar jest tworzony tylko przez projekt Maven, możesz skopiować cały projekt do swojego systemu i uruchomić plik

mvn install

w katalogu projektu. Spowoduje to dodanie pliku jar do katalogu .m2, który jest lokalnym repozytorium maven.

Teraz możesz dodać

<dependency>
     <groupId>copy-from-the=maven-pom-of-existing-project</groupId>
     <artifactId>copy-from-the=maven-pom-of-existing-project</artifactId>
     <version>copy-from-the=maven-pom-of-existing-project</version>
</dependency>

To zapewni, że ty

mvn exec:java 

Pracuje. Jeśli używasz sugerowanych tutaj

<scope>system</scope>

Następnie będziesz musiał dodawać klasy indywidualnie, używając wykonywania z wiersza poleceń.

Możesz dodać zewnętrzne słoiki za pomocą następującego polecenia opisanego tutaj

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> \
-DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>
Bug Killer
źródło
0

Najbardziej wydajnym i najczystszym sposobem rozwiązania tego problemu, jaki znalazłem, jest użycie pakietów Github

  1. Utwórz proste, puste repozytorium publiczne / prywatne na GitHub zgodnie z wymaganiami, niezależnie od tego, czy chcesz, aby Twój zewnętrzny jar był publicznie hostowany, czy nie.

  2. Uruchom poniżej komendę maven, aby wdrożyć zewnętrzny jar w powyższym repozytorium github

    mvn deploy:deploy-file \ -DgroupId= your-group-id \ -DartifactId= your-artifact-id \ -Dversion= 1.0.0 -Dpackaging= jar -Dfile= path-to-file \ -DrepositoryId= id-to-map-on-server-section-of-settings.xml \ -Durl=https://maven.pkg.github.com/github-username/github-reponame-created-in-above-step

    Powyższe polecenie wdroży zewnętrzny jar w repozytorium GitHub, o którym mowa w -Durl=. Możesz odnieść się do tego łącza w temacie Jak wdrażać zależności jako Pakiety GitHub Samouczek wdrażania pakietu GitHub

  3. Po tym można dodać zależność użyciu groupId, artifactIda versionwymienione w powyższym etapie w Maven pom.xmli metęmvn install

  4. Maven pobierze zależność zewnętrznego pliku jar z rejestru pakietów GitHub i udostępni w Twoim projekcie maven.

  5. Aby to zadziałało, musisz również skonfigurować maven settings.xmldo pobierania z rejestru pakietów GitHub.

Nitish Kumar
źródło