wake-up-neo.com

Bewährte Methoden zum Kopieren von Dateien mit Maven

Ich habe Konfigurationsdateien und verschiedene Dokumente, die ich mithilfe von Maven2 aus der Entwicklungsumgebung in das Entwicklungsserververzeichnis kopieren möchte. Seltsamerweise scheint Maven bei dieser Aufgabe nicht stark zu sein.


Einige der Optionen:

  • Verwenden Sie einfach eine Kopie Aufgabe in Maven

<copy file="src/main/resources/config.properties" tofile="${project.server.config}/config.properties"/>

  • Verwenden Sie das Ant-Plugin, um copy von Ant auszuführen.

  • Konstruiere ein Artefakt vom Typ Zip neben dem "Haupt" -Artefakt des POM, das normalerweise vom Typ jar ist, dann auspacken das Artefakt aus dem Repository in das Zielverzeichnis.

  • maven-resources Plugin, wie unten erwähnt.

  • Maven Assembly Plugin - aber das scheint eine Menge manueller Definitionen zu erfordern, wenn ich Dinge einfach und "konventionell" machen möchte.

  • Diese Seite zeigt sogar, wie man ein Plugin zum Kopieren erstellt!

  • maven-upload Plugin, wie unten erwähnt.

  • maven-dependency-plugin mit copy, wie unten erwähnt.


All dies scheint unnötig ad hoc zu sein: Maven soll diese Standardaufgaben ohne viel Aufhebens und Mühen erledigen.

Irgendein Rat?

181
Joshua Fox

Scheuen Sie sich nicht vor dem Antrun-Plugin. Nur weil manche Leute glauben, dass Ant und Maven sich widersprechen, sind sie es nicht. Verwenden Sie die Kopieraufgabe, wenn Sie unvermeidbare Anpassungen vornehmen müssen:

<project>
  [...]
  <build>
    <plugins>
      [...]
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <executions>
          <execution>
            <phase>deploy</phase>
            <configuration>
              <tasks>

                <!--
                  Place any Ant task here. You can add anything
                  you can add between <target> and </target> in a
                  build.xml.
                -->

              </tasks>
            </configuration>
            <goals>
              <goal>run</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

Bei der Beantwortung dieser Frage konzentriere ich mich auf die Details Ihrer Fragen. Wie kopiere ich eine Datei? Die Frage und der Variablenname führen mich zu größeren Fragen wie: "Gibt es eine bessere Möglichkeit, mit der Serverbereitstellung umzugehen?" Verwenden Sie Maven als Build-System, um bereitstellbare Artefakte zu generieren, und führen Sie diese Anpassungen entweder in separaten Modulen oder ganz anderswo durch. Wenn Sie etwas mehr von Ihrer Build-Umgebung freigegeben haben, gibt es möglicherweise einen besseren Weg: Es gibt Plug-ins, um eine Reihe von Servern bereitzustellen. Könnten Sie eine Assembly anhängen, die im Stammverzeichnis des Servers entpackt ist? Welchen Server verwenden Sie?

Ich bin mir wieder sicher, dass es einen besseren Weg gibt.

111
Tim O'Brien
<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.3</version>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>src/main/Java</directory>
            <includes>
                <include> **/*.properties</include>
            </includes>
        </resource>
    </resources>
    ...
</build>
133
peter

Um eine Datei zu kopieren, verwenden Sie:

        <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>copy-resource-one</id>
                    <phase>install</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>

                    <configuration>
                        <outputDirectory>${basedir}/destination-folder</outputDirectory>
                        <resources>
                            <resource>
                                <directory>/source-folder</directory>
                                <includes>
                                    <include>file.jar</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
           </executions>
        </plugin>

Um einen Ordner mit Unterordnern zu kopieren, verwenden Sie die folgende Konfiguration:

           <configuration>
              <outputDirectory>${basedir}/target-folder</outputDirectory>
              <resources>          
                <resource>
                  <directory>/source-folder</directory>
                  <filtering>true</filtering>
                </resource>
              </resources>              
            </configuration>  

Das Maven-Abhängigkeits-Plugin ersparte mir viel Zeit beim Stöbern mit Ameisen-Aufgaben:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>install-jar</id>
            <phase>install</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>...</groupId>
                        <artifactId>...</artifactId>
                        <version>...</version>
                    </artifactItem>
                </artifactItems>
                <outputDirectory>...</outputDirectory>
                <stripVersion>true</stripVersion>
            </configuration>
        </execution>
    </executions>
</plugin>

Das Abhängigkeit: Kopie ist dokumentiert und hat nützlichere Ziele wie das Entpacken.

18
Tires

Für einfache Kopieraufgaben kann ich copy-rename-maven-plugin empfehlen. Es ist einfach und unkompliziert zu bedienen:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>com.coderplus.maven.plugins</groupId>
        <artifactId>copy-rename-maven-plugin</artifactId>
        <version>1.0</version>
        <executions>
          <execution>
            <id>copy-file</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>copy</goal>
            </goals>
            <configuration>
              <sourceFile>src/someDirectory/test.environment.properties</sourceFile>
              <destinationFile>target/someDir/environment.properties</destinationFile>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Wenn Sie mehr als eine Datei kopieren möchten, ersetzen Sie das <sourceFile>...</destinationFile> teil mit

<fileSets>
  <fileSet>
    <sourceFile>src/someDirectory/test.environment.properties</sourceFile>
    <destinationFile>target/someDir/environment.properties</destinationFile>
  </fileSet>
  <fileSet>
    <sourceFile>src/someDirectory/test.logback.xml</sourceFile>
    <destinationFile>target/someDir/logback.xml</destinationFile>
  </fileSet>                
</fileSets>

Darüber hinaus können Sie bei Bedarf mehrere Ausführungen in mehreren Phasen angeben. Das zweite Ziel ist "Umbenennen", das einfach das tut, was es sagt, während der Rest der Konfiguration gleich bleibt. Weitere Verwendungsbeispiele finden Sie auf der Verwendungsseite .

Hinweis : Dieses Plugin kann nur Dateien kopieren, keine Verzeichnisse. (Vielen Dank an @ james.garriss für das Auffinden dieser Einschränkung.)

15
morten.c

Die obige Ant-Lösung ist am einfachsten zu konfigurieren, aber ich hatte Glück mit dem Maven-Upload-Plugin von Atlassian. Ich konnte keine gute Dokumentation finden. Ich verwende sie wie folgt:

<build>
  <plugin>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-upload-plugin</artifactId>
    <version>1.1</version>
    <configuration>
       <resourceSrc>
             ${project.build.directory}/${project.build.finalName}.${project.packaging}
       </resourceSrc>
       <resourceDest>${jboss.deployDir}</resourceDest>
       <serverId>${jboss.Host}</serverId>
       <url>${jboss.deployUrl}</url>
     </configuration>
  </plugin>
</build>

Die Variablen wie "$ {jboss.Host}", auf die oben verwiesen wird, sind in meiner ~/.m2/settings.xml definiert und werden mit Hilfe von Maven-Profilen aktiviert. Diese Lösung ist nicht auf JBoss beschränkt, sondern genau das habe ich meine Variablen genannt. Ich habe ein Profil für Entwickler, Test und Live. Um mein Ohr auf eine JBoss-Instanz in einer Testumgebung hochzuladen, würde ich Folgendes ausführen:

mvn upload:upload -P test

Hier ist ein Snipet aus settings.xml:

<server>
  <id>localhost</id>
  <username>username</username>
  <password>{Pz+6YRsDJ8dUJD7XE8=} an encrypted password. Supported since maven 2.1</password>
</server>
...
<profiles>
  <profile>
    <id>dev</id>
    <properties>
      <jboss.Host>localhost</jboss.Host> 
      <jboss.deployDir>/opt/jboss/server/default/deploy/</jboss.deployDir>
      <jboss.deployUrl>scp://[email protected]</jboss.deployUrl>
    </properties>
  </profile>
  <profile>
    <id>test</id>
    <properties>
       <jboss.Host>testserver</jboss.Host>
       ...

Anmerkungen: Das Atlassian Maven Repo mit diesem Plugin ist hier: https://maven.atlassian.com/public/

Ich empfehle, die Quellen herunterzuladen und in der Dokumentation nachzuschlagen, um alle Funktionen des Plugins zu sehen.

`

6
Kyle Renfro

Nun, Maven sollte nicht gut darin sein, feine granulare Aufgaben zu erledigen, es ist keine Skriptsprache wie Bash oder Ameise, es ist eher aussagekräftig - Sie sagen - ich brauche einen Krieg oder ein Ohr, und Sie verstehen es. Wenn Sie jedoch anpassen müssen, wie der Krieg oder das Ohr im Inneren aussehen sollen, haben Sie ein Problem. Es ist einfach nicht prozedural wie eine Ameise, sondern deklarativ. Dies hat am Anfang einige Vorzüge und könnte am Ende viele Nachteile haben.

Ich denke, das ursprüngliche Konzept war, feine Plugins zu haben, die "nur funktionieren", aber die Realität sieht anders aus, wenn Sie nicht-standardmäßige Sachen machen.

Wenn Sie jedoch genügend Aufwand in Ihre poms und einige benutzerdefinierte Plugins stecken, erhalten Sie eine viel bessere Build-Umgebung als zum Beispiel mit ant (hängt natürlich von Ihrem Projekt ab, dies wird jedoch für größere Projekte immer wahrer).

5
siddhadev

Eine generische Methode zum Kopieren beliebiger Dateien ist die Verwendung der Transportabstraktion Maven Wagon . Es kann verschiedene Ziele über Protokolle wie file, HTTP, FTP, SCP oder WebDAV behandeln.

Es gibt einige Plugins, mit denen Dateien mithilfe von Wagon kopiert werden können. Am bemerkenswertesten sind:

  • Sofort einsatzbereit Maven Deploy Plugin

    Es gibt das deploy-file Ziel. Es ist ziemlich unflexibel, kann aber die Arbeit erledigen:

    mvn deploy:deploy-file -Dfile=/path/to/your/file.ext -DgroupId=foo 
    -DartifactId=bar -Dversion=1.0 -Durl=<url> -DgeneratePom=false
    

    Ein wesentlicher Nachteil der Verwendung von Maven Deploy Plugin Ist, dass es für die Arbeit mit Maven-Repositorys vorgesehen ist. Es setzt bestimmte Strukturen und Metadaten voraus. Sie können sehen, dass die Datei unter foo/bar/1.0/file-1.0.ext Platziert wird und Prüfsummendateien erstellt werden. Daran führt kein Weg vorbei.

  • Wagon Maven Plugin

    Verwenden Sie das upload-single Ziel :

    mvn org.codehaus.mojo:wagon-maven-plugin:upload-single
    -Dwagon.fromFile=/path/to/your/file.ext -Dwagon.url=<url>
    

    Die Verwendung von Wagon Maven Plugin Zum Kopieren ist unkompliziert und scheint am vielseitigsten zu sein.


In den obigen Beispielen kann <url> Von jedem unterstützten Protokoll sein. Siehe die Liste der vorhandenen Wagenanbieter . Zum Beispiel

  • datei lokal kopieren: file:///copy/to
  • kopieren der Datei auf einen Remote-Host mit SSH: scp://Host:22/copy/to


In den obigen Beispielen werden Plugin-Parameter in der Befehlszeile übergeben. Alternativ können Plugins direkt in POM konfiguriert werden. Dann lautet der Aufruf einfach mvn deploy:[email protected]. Oder es kann an eine bestimmte Erstellungsphase gebunden sein.


Bitte beachten Sie, dass für Protokolle wie SCP eine Erweiterung in Ihrem POM definiert werden muss:

<build>
  [...]
  <extensions>
    <extension>
      <groupId>org.Apache.maven.wagon</groupId>
      <artifactId>wagon-ssh</artifactId>
      <version>2.12</version>
    </extension>
  </extensions>


Wenn für das Ziel, an das Sie kopieren, eine Authentifizierung erforderlich ist, können Anmeldeinformationen über Server settings bereitgestellt werden. repositoryId/serverId, das an die Plugins übergeben wird, muss mit dem in den Einstellungen definierten Server übereinstimmen.

4
user318054

Ich habe sehr gute Erfahrungen mit copy-maven-plugin gemacht. Die Syntax ist im Vergleich zum Maven-Resources-Plugin wesentlich komfortabler und übersichtlicher.

4
azerole

Ich kann nur davon ausgehen, dass Ihre Eigenschaft $ {project.server.config} benutzerdefiniert ist und sich außerhalb des Standardverzeichnislayouts befindet.

Wenn ja, dann würde ich die Kopieraufgabe verwenden.

3
whaley

Eine andere Möglichkeit besteht darin, diese Dinge mit dem Assembly-Plugin zu einem Artefakt zu bündeln. Dann können Sie das Abhängigkeits-Plugin verwenden, um diese Dateien zu entpacken, wo Sie möchten. Es gibt auch Kopierziele im Abhängigkeits-Plugin, um Artefakte zu kopieren.

2
Brian Fox

Für diese Antwort konnte ich verschiedene Quellen zusammenstellen:

...
<repository>
    <id>atlassian</id>
    <name>Atlassian Repo</name>
    <url>https://maven.atlassian.com/content/repositories/atlassian-public</url>
</repository>
...
<dependency>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-upload-plugin</artifactId>
    <version>1.1</version>
</dependency>
...
<plugin>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-upload-plugin</artifactId>
    <version>1.1</version>
    <configuration>
        <serverId>jira-repo</serverId>
        <resourceSrc>
            ${project.build.directory}/${project.build.finalName}.${project.packaging}
        </resourceSrc>
        <resourceDest>opt/jira/webapps</resourceDest> <!-- note: no leading slash -->
        <url>scp://[email protected]</url>
    </configuration>
</plugin>
...

Von ~/.m2/settings.xml:

...
<servers>
  <server>
    <id>jira-repo</id>
    <username>myusername</username>
    <password>mypassword</password>
  </server>
</servers>
...

Führen Sie dann den Befehl aus: (das -X ist für das Debuggen)

mvn -X upload:upload

1
Brett Dutton