Maven: Fügen Sie einem Glas eine Abhängigkeit über den relativen Pfad hinzu

232

Ich habe ein proprietäres Glas, das ich als Abhängigkeit zu meinem Pom hinzufügen möchte.

Aber ich möchte es nicht zu einem Repository hinzufügen. Der Grund dafür ist, dass ich möchte, dass meine üblichen Maven-Befehle wie mvn compileusw. sofort funktionieren. (Ohne von den Entwicklern zu verlangen, dass sie es selbst zu einem Repository hinzufügen).

Ich möchte, dass sich das JAR in einer Drittanbieter-Bibliothek in der Quellcodeverwaltung befindet und über den relativen Pfad aus der Datei pom.xml mit ihm verknüpft ist.

Kann das gemacht werden? Wie?

Flybywire
quelle

Antworten:

343

Ich möchte, dass sich das JAR in einer Drittanbieter-Bibliothek in der Quellcodeverwaltung befindet und über den relativen Pfad aus der Datei pom.xml mit ihm verknüpft ist.

Wenn Sie dies wirklich möchten (verstehen Sie, wenn Sie kein Unternehmens-Repository verwenden können), würde ich empfehlen, ein für das Projekt lokales "Datei-Repository" zu verwenden und keinesystem Abhängigkeit mit Gültigkeitsbereich zu verwenden. Der systemUmfang sollte vermieden werden. Solche Abhängigkeiten funktionieren in vielen Situationen nicht gut (z. B. bei der Montage). Sie verursachen mehr Probleme als Vorteile.

Deklarieren Sie stattdessen ein lokales Repository für das Projekt:

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

Installieren Sie dort Ihre Drittanbieter-Bibliothek install:install-filemit dem folgenden localRepositoryPathParameter:

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

Update: Es scheint, dass bei Verwendung der Version 2.2 des Plugins install:install-fileignoriert wird localRepositoryPath. Es funktioniert jedoch mit Version 2.3 und höher des Plugins. Verwenden Sie also den vollständig qualifizierten Namen des Plugins, um die Version anzugeben:

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>

Dokumentation zum Maven-Install-Plugin

Deklarieren Sie es schließlich wie jede andere Abhängigkeit (jedoch ohne den systemUmfang):

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

Dies ist meiner Meinung nach eine bessere Lösung als die Verwendung eines systemBereichs, da Ihre Abhängigkeit wie ein guter Bürger behandelt wird (z. B. wird sie in eine Versammlung aufgenommen und so weiter).

Jetzt muss ich erwähnen, dass der "richtige Weg", um mit dieser Situation in einem Unternehmensumfeld umzugehen (hier möglicherweise nicht der Fall), die Verwendung eines Unternehmensrepositorys wäre.

Pascal Thivent
quelle
2
Dies ist eine großartige Idee, aber unter Maven 2.2.1 scheint das Installations-Plugin dies zu ignorieren localRepositoryPath ...
Jake
1
Warum ein lokales Repo deklarieren? Warum nicht einfach mit dem Rest in ~ / .m2 / gehen lassen?
Leif Gruenwoldt
6
@ leif81 Da dann das Repo und die Bibliotheken in das SCM-Repository eingecheckt werden -> Jeder, der eine Quellprüfung durchführt, verfügt über alles, was er zum Erstellen einer Kopie der Bibliothek / Anwendung benötigt.
Darth Android
6
Ich hatte das gleiche Problem wie @lemon, das ich behoben habe, indem ich stattdessen basedir/./my-local-repoeine Single .verwendet habe.
Brian
2
Verpackung muss Glas sein, daher -Dpackaging = Glas
Danila Piatov
127

Verwenden des systemBereichs. ${basedir}ist das Verzeichnis deines Poms.

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

Es ist jedoch ratsam, dass Sie Ihr JAR im Repository installieren und nicht an das SCM übergeben - schließlich versucht Maven dies zu beseitigen.

Bozho
quelle
15
Das Scope-System muss überall vermieden werden, wo es möglich ist. Die Installation der JAR im Repository ist eine bessere Lösung ...
Gandalf StormCrow
14
ja wenn möglich Er sagte ausdrücklich, dass er es nicht in das Repository stellen will. Ich habe einen Kommentar hinzugefügt, um darauf hinzuweisen, dass dies keine gute Praxis ist. Aber es funktioniert.
Bozho
groovy, Ihre Lösung ist die akzeptabelste, denke ich. Ich habe die Frage völlig falsch verstanden
Ameise
Ja - die Frage selbst schließt die beste Antwort aus. Das Einfügen von allem in Ihren einzelnen Versionsverwaltungsserver hat wenig mit "sofort einsatzbereit" zu tun. Vielmehr muss einfach alles "kontrolliert" werden. Checken Sie poms & settings.xml ein (zeigen Sie auf das interne Repo) und verwenden Sie zwei Server für Ihr Projekt: (1) Quellcodeverwaltung, (2) generierte Artefaktsteuerung. Das Einchecken von Jars macht ungefähr so ​​viel Sinn wie das Einchecken von DLLs (mein altes Unternehmen hat tatsächlich Jars & lib.a / .so / .dlls eingecheckt. Unser p4-Server war danach so langsam, dass einige hg für den Tag heimlich verwendeten -to-day work. Problem gelöst?
Michael
Gibt es eine Möglichkeit, ein Verzeichnis anzugeben, das stattdessen Gläser enthält, damit wir nicht jedes einzelne hinzufügen müssen, so wie es gradle tun kann?
Dean Hiller
29

Dies ist eine weitere Methode zusätzlich zu meiner vorherigen Antwort unter Kann ich dem Maven 2-Build-Klassenpfad Jars hinzufügen, ohne sie zu installieren?

Dies wird das Limit bei Verwendung von Builds mit mehreren Modulen umgehen, insbesondere wenn auf die heruntergeladene JAR in untergeordneten Projekten außerhalb des übergeordneten Projekts verwiesen wird. Dies reduziert auch den Einrichtungsaufwand, indem die POM- und SHA1-Dateien als Teil des Builds erstellt werden. Außerdem kann sich die Datei an einer beliebigen Stelle im Projekt befinden, ohne die Namen zu korrigieren oder der Maven-Repository-Struktur zu folgen.

Dies verwendet das Maven-Install-Plugin. Damit dies funktioniert, müssen Sie ein Projekt mit mehreren Modulen einrichten und ein neues Projekt haben, das den Build darstellt, um Dateien im lokalen Repository zu installieren und sicherzustellen, dass eines das erste ist.

Ihr Multi-Modul-Projekt pom.xml würde folgendermaßen aussehen:

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

Die Datei repository / pom.xml enthält dann die Definitionen zum Laden der JARs, die Teil Ihres Projekts sind. Im Folgenden finden Sie einige Ausschnitte aus der Datei pom.xml.

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

Die POM-Verpackung verhindert, dass Tests durchgeführt oder JAR-Dateien kompiliert oder generiert werden. Das Fleisch der Datei pom.xml befindet sich im Build-Bereich, in dem das Maven-Install-Plugin verwendet wird.

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

Um mehr als eine Datei zu installieren, fügen Sie einfach weitere Ausführungen hinzu.

Archimedes Trajano
quelle
Dies ist das einzige, was für mein Multi-Modul-Projekt funktioniert hat. Der lokale <repository> -Ansatz aus einem unbekannten Grund hat nicht funktioniert. So danke!
Lonzak
10

Das funktioniert bei mir: Nehmen wir an, ich habe diese Abhängigkeit

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

Fügen Sie dann den Klassenpfad für Ihre Systemabhängigkeit manuell wie folgt hinzu

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

Vollständige Konfiguration:

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

Ich habe zuvor über ein Muster dafür geschrieben.

Es ist der von Pascal vorgeschlagenen Lösung sehr ähnlich, verschiebt jedoch alle diese Abhängigkeiten in ein dediziertes Repository-Modul, sodass Sie es nicht überall wiederholen müssen, wenn die Abhängigkeit verwendet wird, wenn es sich um einen Build mit mehreren Modulen handelt.

Brett Porter
quelle
6

Fügen Sie dies grundsätzlich zur Datei pom.xml hinzu:

...

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

wir haben auf gradle umgestellt und das funktioniert in gradle viel besser;). Wir geben nur einen Ordner an, in den wir Gläser für vorübergehende Situationen wie diese ablegen können. Wir haben immer noch die meisten unserer Gläser im typischen Abschnitt zum Abhängigkeitsmanagement definiert (dh das gleiche wie bei maven). Dies ist nur eine weitere Abhängigkeit, die wir definieren.

Im Grunde genommen können wir jetzt einfach jedes gewünschte JAR zum vorübergehenden Testen in unser lib-Verzeichnis ablegen, wenn es sich nicht irgendwo in einem Maven-Repository befindet.

Dean Hiller
quelle
1
Können Sie ein Beispiel geben, wie Sie das gemacht haben?
Thomas
2

Eine kleine Ergänzung zu der von Pascal veröffentlichten Lösung

Als ich dieser Route folgte, wurde bei der Installation von ojdbc jar ein Fehler in maven angezeigt.

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

Nach dem Hinzufügen von -DpomFile wurde das Problem behoben.

$ 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
quelle
0

Sie können Eclipse verwenden, um eine ausführbare Jar: Export / Runable Jar-Datei zu generieren

user1942990
quelle
Ich bin mir nicht sicher, ob das die Frage beantwortet. Er hat die Akte schon als Glas.
Johannes Jander
Eclipse unterstützt Uberjar oder schattiertes Glas, daher ist es eine Lösung, aber nicht für Maven
Alex Lehmann