Mavenでファイルをコピーするためのベストプラクティス


193

Maven2を使用して、開発環境からdev-serverディレクトリにコピーする構成ファイルとさまざまなドキュメントがあります。不思議なことに、Mavenはこのタスクに強いとは思えません。

オプションの一部:

  • Mavenでコピータスクを簡単に使用する
<copy file="src/main/resources/config.properties" tofile="${project.server.config}/config.properties"/>
  • Antプラグインを使用して、Ant からのコピーを実行します

    • タイプのアーティファクト構築ジッパーを通常型のあるPOMの「主」アーティファクトと一緒に、ジャー、次にアンパックターゲットディレクトリにリポジトリからのアーティファクト。

    • 後述するmaven-resourcesプラグイン。

    • Mavenアセンブリプラグイン-しかし、これを簡単かつ「従来どおり」実行したい場合は、多くの手動定義が必要なようです。

    • このページでは、コピーを実行するためのプラグインの作成方法も示しています。

    • 以下で説明するように、maven-uploadプラグイン。

    • 以下で説明するように、maven-dependency-plugin with copy


これらすべては不必要にその場限りのように見えます。Mavenは、これらの標準的なタスクを大騒ぎせずに行うことに優れているはずです。

何かアドバイス?


2
Mavenはフェーズを含むライフサイクルの考え方に基づいて構築されています。ランダムファイルのリモートサーバータスクへのコピーは、実際にはこれに適合しません。常にプロジェクト全体を考えてください。
アンドレ・

3
「これらすべては不必要にその場限りのように見えます。Mavenは大騒ぎせずにこれらの標準的なタスクを実行することに優れているはずです。」あなたがしていること自体は標準的なタスクではありません。アーティファクトがwar / earの場合、これは、cargoプラグイン(cargo.codehaus.org/Maven2+plugin#Maven2plugin-get…)を使用するのと同じくらい簡単です。説明する内容は、標準のJavaアプリケーションコンテナのデプロイメントではなく、デプロイメントの方法に非常に固有のように聞こえます。Mavenは、実際のサーバーへのデプロイ時のアクティビティを処理するようには調整されていません。ビルド/開発アクティビティをさらに調整するためのものです。
クジラ2009

67
@André:私はその議論を何度も繰り返し聞いていますが、申し訳ありませんが、それはBSです。プロジェクト全体の考え方に問題はありませんが、適切なビルドシステムの一部は、ファイルのコピーなど、タスクXを簡単に実行できる機能である必要があります。Mavenではそれができません。build-scripts-are-codeパラダイム(Gradle、SBT、またはBuildrなど)を採用する非常に多くのプロジェクトが最近ポップアップしたのには理由があります。
Matthias

アーティファクトを構築するためのpom.xml と、指定されたアーティファクトをデプロイするためのpom.xmlを用意することをお勧めします。
–ThorbjørnRavn Andersen 2012

上記のすべての提案では、特定のファイルを別のプロジェクト/アーティファクトからMavenプロジェクトにコピーできません。jarになるアーティファクトのsrc / main / folderの下にいくつかのファイルがあり、依存関係コピーのmavenプラグインを使用してみましたが、どのファイルをコピーするかを言う方法が見つからず、jar全体を取得します常にアセンブリファイル内のファイル。リソースなど、ここにある他のすべての提案では、プロジェクト内のリソースではなくアーティファクトを指定できないようです
Alexandre Thenorio

回答:


119

Antrunプラグインを避けないでください。AntとMavenが反対していると考える傾向があるという理由だけで、彼らは反対していません。やむを得ず1回限りのカスタマイズを実行する必要がある場合は、コピータスクを使用します。

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

この質問に答えるにあたり、私はあなたの質問の詳細に焦点を当てています。ファイルをコピーするにはどうすればよいですか?質問と変数名から、「サーバーのプロビジョニングを処理するためのより良い方法はありますか?」のようなより大きな質問に私を導きました。デプロイ可能なアーティファクトを生成するビルドシステムとしてMavenを使用し、これらのカスタマイズを個別のモジュールまたは他の場所で完全に実行します。ビルド環境をもう少し共有している場合は、もっと良い方法があるかもしれません-複数のサーバーをプロビジョニングするプラグインがあります。サーバーのルートに解凍されたアセンブリを接続できますか?どのサーバーを使用していますか?

繰り返しますが、もっと良い方法があると確信しています。


タスク記述子は非推奨になりましたか?
マット

3
@Mattはい、taskパラメーターは非推奨になりました(Antrunプラグイン)。target代わりに使用する必要があります(1.5以降)。残念ながら、これを混同する例があります。たとえば、targetパラメータおよびversion1.5未満。
cuh

これはどのように受け入れられた答えになりますか?コピーを単純なものにするために、Mavenに変更要求があることは間違いありません。
Wolfgang Fahl

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

@Peter、ありがとう。Antrunではなく、resources-plugin copy-resourcesゴールを使用します。後者は実際にははるかにシンプルで直感的に定義できますが、すべてのMavenカスタムプロパティ(<properties>セクションで定義)をantrunに渡すことができなかったため(バージョン1.3)、リソースプラグインに切り替えました。
Cornel Masson、2010年

2
以前はこれが正解だと思っていました...リソースプラグインにスキップ構成がないことに気づくまでは。Antrunは進むべき道です。
マイクポスト

スキッププロファイルを作成することは難しくありません。antrunを使用したことがないので、どちらが簡単/優れているかは言えません
Vivek Chavda

40

ファイルをコピーするには、以下を使用します。

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

サブフォルダーを含むフォルダーをコピーするには、次の構成を使用します。

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

Mavenでのフィルタリングは文字列補間を参照するため、変数<filtering>を使用するスクリプトファイルなどの不要な変更を防ぐために省略し${...}ます。
GeroldBroserがモニカを2018

20

Maven依存関係プラグインにより、私は多くの時間をantタスクをいじる手間を省きました。

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

依存関係:コピーが documentendあり、そしてアンパックなどのより有用な目標を持っています。


3
私は何年もAntを使用していませんでした。そのような単純なことでAntを使い始めたくありません。この回答に感謝します。
ギュスターヴ

17

単純なコピータスクの場合は、copy-rename-maven-pluginをお勧めします。使い方は簡単で簡単です。

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

複数のファイルをコピーする場合は、<sourceFile>...</destinationFile>パーツを

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

さらに、必要に応じて複数のフェーズで複数の実行を指定できます。2番目の目標は「名前の変更」です。これにより、残りの構成は同じまま、単に名前が変更されます。その他の使用例については、使用法ページを参照してください

:このプラグインは、ディレクトリではなくファイルのみをコピーできます。(この制限を見つけてくれた@ james.garrissに感謝します。)


2
私はこのプラグインが好きですが、ディレクトリをコピーできないのは驚くべきことです。
james.garriss

3
@ james.garriss私はこの制限を認識していませんでしたが、残念ながらあなたは正しいです。これを私の回答に編集して、一部の人が自分でこれを見つける時間を節約できるようにします。
morten.c

7

上記のantソリューションは設定が最も簡単ですが、アトラシアンのmaven-upload-pluginを使用して運が良かったです。適切なドキュメントが見つかりませんでした。使用方法は次のとおりです。

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

上記の「$ {jboss.host}」のような変数はmy〜/ .m2 / settings.xmlで定義され、Mavenプロファイルを使用してアクティブ化されます。このソリューションはJBossに限定されていません。これは、私が変数に付けた名前です。開発、テスト、およびライブのプロファイルがあります。テスト環境でjbossインスタンスに自分の耳をアップロードするには、次のコマンドを実行します。

mvn upload:upload -P test

以下は、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://root@localhost</jboss.deployUrl>
    </properties>
  </profile>
  <profile>
    <id>test</id>
    <properties>
       <jboss.host>testserver</jboss.host>
       ...

注:このプラグインを持つAtlassian mavenリポジトリはこちらです:https : //maven.atlassian.com/public/

プラグインが提供するすべての機能を確認するには、ソースをダウンロードし、内部のドキュメントを確認することをお勧めします。

`


5

まあ、Mavenはきめ細かいタスクを実行するのが得意ではありません。bashやantのようなスクリプト言語ではなく、むしろ宣言型です。ただし、戦争や耳が内部でどのように見えるかをカスタマイズする必要がある場合は、問題があります。antのような手続き型ではなく、宣言型です。これは最初にいくつかの長所があり、最後に多くの短所を持つ可能性があります。

最初のコンセプトは細かいプラグインを用意することだったと思いますが、それは「うまくいく」だけですが、非標準的なことを行うと現実は異なります。

ただし、pomといくつかのカスタムプラグインに十分な労力をかけると、たとえばantのように、はるかに優れたビルド環境が得られます(もちろん、プロジェクトによって異なりますが、より大きなプロジェクトではますます真実になります)。



4

任意のファイルをコピーする一般的な方法は、Maven Wagonトランスポート抽象化を利用することです。それは、などのプロトコルを介した様々な目的地を扱うことができfileHTTPFTPSCPまたはWebDAV

を使用してファイルをコピーする機能を提供するプラグインがいくつかありますWagon。最も注目すべき点は次のとおりです。

  • すぐに使える 使えるMaven Deployプラグイン

    deploy-file目標があります。それは非常に柔軟性がありませんが、仕事を成し遂げることができます:

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

    使用Maven Deploy Pluginすることの大きな欠点は、Mavenリポジトリーで動作するように指定されていることです。特定の構造とメタデータを想定しています。ファイルが配置されfoo/bar/1.0/file-1.0.ext、チェックサムファイルが作成されていることがわかります。これを回避する方法はありません。

  • Wagon Mavenプラグイン

    upload-single目標を使用する:

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

    Wagon Maven Pluginコピーの使用は簡単で、最も用途が広いようです。


上記の例<url>では、サポートされている任意のプロトコルを使用できます。既存のWagonプロバイダーのリストを参照してください。例えば

  • ローカルにファイルをコピー: file:///copy/to
  • 実行中のリモートホストにファイルをコピーしていますSSHscp://host:22/copy/to


上記の例では、コマンドラインでプラグインパラメータを渡します。または、プラグインはで直接設定することもできますPOM。次に、呼び出しは単純に次のようになりますmvn deploy:deploy-file@configured-execution-idます。または、特定のビルドフェーズにバインドできます。


機能するようなプロトコルでSCPは、拡張機能を定義する必要があることに注意してくださいPOM

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


コピー先の宛先で認証が必要な場合は、Server設定を介して認証情報を提供できますrepositoryId/ serverIdプラグインに渡される設定で定義されているサーバーと一致する必要があります。


3

$ {project.server.config}プロパティはカスタムで定義されたものであり、標準のディレクトリレイアウトの外にあるとしか想定できません。

その場合は、コピータスクを使用します。


ファイルを標準のディレクトリレイアウトに配置するとします。Mavenはzip / jarではなく、そのままターゲットにコピーできますか?
ジョシュアフォックス

2

別の方法は、アセンブリプラグインを使用して、これらをアーティファクトにバンドルすることです。次に、依存関係プラグインを使用して、これらのファイルを必要な場所に解凍できます。アーティファクトをコピーするための依存関係プラグインにはコピー目標もあります。


1

私はこの答えのためにいくつかの異なる情報源をつなぎ合わせることができました:

...
<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://root@jira</url>
    </configuration>
</plugin>
...

から~/.m2/settings.xml

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

次に、コマンドを実行します(-Xはデバッグ用です)。

mvn -X upload:upload


-1

上記の良い答えのいくつかを要約すると:Mavenはモジュールを構築し、結果をMavenリポジトリーにコピーするように設計されています。デプロイメント/インストーラー入力ディレクトリへのモジュールのコピーは、Ant / Maven コピーコマンドなどを使用して、Mavenのコア機能のコンテキスト外で実行する必要があります。


AntはMavenのコア機能に属し、Wagonも属します(その周りのプラグインは公式のMavenコアプラグインではありません)。
GeroldBroserがモニカを2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.