Thực hành tốt nhất để sao chép tệp bằng Maven


193

Tôi có các tệp cấu hình và các tài liệu khác nhau mà tôi muốn sao chép từ môi trường dev sang thư mục dev-server bằng Maven2. Kỳ lạ thay, Maven dường như không mạnh mẽ trong nhiệm vụ này.

Một số tùy chọn:

  • Sử dụng đơn giản một tác vụ sao chép trong Maven
<copy file="src/main/resources/config.properties" tofile="${project.server.config}/config.properties"/>
  • Sử dụng plugin Ant để thực thi sao chép từ Ant.

    • Xây dựng một tạo phẩm của loại zip , bên cạnh tạo phẩm "chính" của POM thường là loại jar , sau đó giải nén tạo phẩm đó từ kho lưu trữ vào thư mục đích.

    • plugin maven-resource , như được đề cập dưới đây.

    • Plugin Maven hội - nhưng điều này dường như đòi hỏi rất nhiều định nghĩa thủ công, khi tôi muốn làm mọi thứ một cách đơn giản và "thông thường".

    • Trang này thậm chí còn cho thấy cách xây dựng một plugin để sao chép!

    • plugin maven-upload , như được đề cập dưới đây.

    • maven-phụ thuộc-plugin với bản sao , như được đề cập dưới đây.


Tất cả những điều này dường như không cần thiết ad hoc: Maven được cho là xuất sắc trong việc thực hiện các nhiệm vụ tiêu chuẩn này mà không phiền phức.

Có lời khuyên nào không?


2
Maven được xây dựng dựa trên ý tưởng về vòng đời với các giai đoạn, các tệp ngẫu nhiên sao chép vào tác vụ máy chủ từ xa không thực sự phù hợp với điều này. Luôn luôn nghĩ về dự án của bạn như một toàn thể.
André

3
"Tất cả những điều này dường như không cần thiết phải trực tiếp: Maven được cho là xuất sắc trong việc thực hiện các nhiệm vụ tiêu chuẩn này mà không phiền phức." Những gì bạn đang làm không phải là một nhiệm vụ tiêu chuẩn. Nếu vật phẩm của bạn là một cuộc chiến / tai, thì điều này sẽ đơn giản như việc sử dụng plugin hàng hóa (Freight.codehaus.org/Maven2+plugin#Maven2plugin-get đấm). Những gì bạn đang mô tả âm thanh rất cụ thể đối với cách bạn đang triển khai và không triển khai bộ chứa ứng dụng java tiêu chuẩn. Maven không thực sự hướng đến việc xử lý các hoạt động thời gian triển khai cho các máy chủ trực tiếp - nó hướng nhiều hơn đến các hoạt động xây dựng / phát triển.
cá voi

67
@ André: Tôi nghe lập luận đó nhiều lần, nhưng xin lỗi, đó là BS. Không có gì sai khi nghĩ về toàn bộ dự án, nhưng một phần của bất kỳ hệ thống xây dựng tử tế nào cũng phải là chức năng cho phép tôi đạt được nhiệm vụ X theo cách đơn giản, chẳng hạn như sao chép tệp và Maven không thể làm điều đó. Có một lý do tại sao rất nhiều dự án xuất hiện gần đây bao trùm mô hình mã-kịch bản xây dựng (như Gradle, SBT hoặc Buildr).
Matthias

Tôi khuyên bạn nên có một pom.xml để xây dựng các tạo phẩm và một cái khác để triển khai một tạo phẩm nhất định.
Thorbjørn Ravn Andersen

Tất cả các đề xuất ở trên dường như vẫn không cho phép tôi sao chép một tệp cụ thể từ một dự án / tạo tác khác vào dự án maven. Tôi có một số tệp trong src / main / thư mục trong một tạo phẩm trở thành một jar và tôi đã thử sử dụng plugin maven sao chép phụ thuộc tuy nhiên tôi không tìm thấy cách nào để nói các tệp tôi muốn sao chép và tôi nhận được toàn bộ tệp tập tin trong tập tin lắp ráp tất cả các thời gian. Tất cả các đề xuất khác ở đây, như tài nguyên, dường như không cho phép tôi chỉ định một vật phẩm thay vì tài nguyên bên trong dự án
Alexandre Thenorio

Câu trả lời:


119

Đừng né tránh plugin Antrun. Chỉ vì một số người có xu hướng nghĩ rằng Ant và Maven đối lập nhau, nhưng họ thì không. Sử dụng tác vụ sao chép nếu bạn cần thực hiện một số tùy chỉnh một lần không thể tránh khỏi:

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

Để trả lời câu hỏi này, tôi đang tập trung vào các chi tiết về những gì bạn đã hỏi. Làm cách nào để sao chép một tập tin? Câu hỏi và tên biến dẫn tôi đến một câu hỏi lớn hơn như: "Có cách nào tốt hơn để đối phó với việc cung cấp máy chủ không?" Sử dụng Maven như một hệ thống xây dựng để tạo ra tạo phẩm có thể triển khai, sau đó thực hiện các tùy chỉnh này trong các mô-đun riêng biệt hoặc ở một nơi khác hoàn toàn. Nếu bạn đã chia sẻ thêm một chút về môi trường xây dựng của mình, có thể có một cách tốt hơn - có các plugin để cung cấp một số máy chủ. Bạn có thể đính kèm một hội đồng được giải nén trong thư mục gốc của máy chủ không? Bạn đang sử dụng máy chủ nào?

Một lần nữa, tôi chắc chắn có một cách tốt hơn.


Là mô tả nhiệm vụ bây giờ không dùng nữa?
Matt

3
@Matt Có, tasktham số hiện không được chấp nhận ( Plugin Antrun ). Bạn nên sử dụng targetthay thế (kể từ 1.5). Thật không may, có những ví dụ trộn lẫn điều này; ví dụ: targettham số và version<1,5.
cuh

Làm thế nào đây có thể là câu trả lời được chấp nhận? Chắc chắn phải có một yêu cầu thay đổi đối với maven để sao chép một điều đơn giản.
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>

Cảm ơn @Peter, điều đó rất hữu ích. Bây giờ tôi sử dụng mục tiêu sao chép tài nguyên-plugin thay vì chống lỗi. Cái sau thực sự đơn giản và trực quan hơn nhiều để định nghĩa, nhưng tôi không thể lấy nó (phiên bản 1.3) để chuyển tất cả các thuộc tính tùy chỉnh Maven (được xác định trong phần <property>) để chống lỗi, vì vậy tôi đã chuyển sang plugin-resource.
Cornel Masson

2
Tôi đã từng nghĩ đây là câu trả lời đúng ... cho đến khi tôi nhận ra rằng plugin tài nguyên không có cấu hình bỏ qua. Antrun là con đường để đi.
Mike Post

Không nên khó tạo hồ sơ bỏ qua. Không được sử dụng chống lỗi, vì vậy tôi không thể nói cái nào dễ hơn / tốt hơn
Vivek Chavda

40

Để sao chép một tập tin sử dụng:

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

Để sao chép thư mục với các thư mục con, sử dụng cấu hình tiếp theo:

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

Lọc trong Maven đề cập đến phép nội suy chuỗi, vì vậy tôi bỏ qua <filtering>để ngăn các thay đổi không mong muốn đối với các tệp script sử dụng ${...}các biến.
GeroldBroser phục hồi Monica

20

Plugin phụ thuộc maven giúp tôi tiết kiệm rất nhiều thời gian với các tác vụ 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>

Sự phụ thuộc: sao chép là documentend và có nhiều mục tiêu hữu ích hơn như giải nén.


3
Tôi đã không sử dụng Ant trong nhiều năm và tôi không muốn bắt đầu làm điều đó vì một điều đơn giản như vậy. Vì vậy, cảm ơn câu trả lời này.
Gustave

17

Đối với một tác vụ sao chép đơn giản, tôi có thể khuyên bạn nên sao chép-đổi tên-maven-plugin . Nó đơn giản và dễ sử dụng:

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

Nếu bạn muốn sao chép nhiều hơn một tệp, hãy thay thế <sourceFile>...</destinationFile>phần đó bằng

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

Hơn nữa, bạn có thể chỉ định nhiều lần thực hiện trong nhiều giai đoạn nếu cần, mục tiêu thứ hai là "đổi tên", chỉ đơn giản là thực hiện những gì nó nói trong khi phần còn lại của cấu hình giữ nguyên. Để biết thêm các ví dụ sử dụng, hãy tham khảo Trang sử dụng .

Lưu ý : Plugin này chỉ có thể sao chép các tập tin, không phải thư mục. (Cảm ơn @ james.garriss vì đã tìm thấy giới hạn này.)


2
Mặc dù tôi thích plugin này, nhưng thật đáng kinh ngạc là nó không thể sao chép các thư mục.
james.garriss

3
@ james.garriss Tôi không nhận thức được giới hạn này nhưng không may là bạn đúng. Tôi sẽ chỉnh sửa câu trả lời này để có thể tiết kiệm thời gian cho một số người tìm thấy điều này bằng chính họ.
morten.c

7

Giải pháp ant ở trên là dễ cấu hình nhất, nhưng tôi đã gặp may khi sử dụng plugin maven-upload-plugin từ Atlassian. Tôi không thể tìm thấy tài liệu tốt, đây là cách tôi sử dụng nó:

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

Các biến như "$ {jboss.host}" được tham chiếu ở trên được xác định trong ~ / .m2 / settings.xml của tôi và được kích hoạt bằng các cấu hình maven. Giải pháp này không bị hạn chế đối với JBoss, đây chỉ là những gì tôi đặt tên cho các biến của mình. Tôi có một hồ sơ cho dev, thử nghiệm và sống. Vì vậy, để tải tai của tôi lên một ví dụ jboss trong môi trường thử nghiệm, tôi sẽ thực hiện:

mvn upload:upload -P test

Đây là một snipet từ 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>
       ...

Ghi chú: Repo Atlassian maven có plugin này ở đây: https://maven.atlassian.com/public/

Tôi khuyên bạn nên tải xuống các nguồn và xem tài liệu bên trong để xem tất cả các tính năng mà plugin cung cấp.

`


5

Chà, maven không được coi là giỏi trong việc thực hiện các nhiệm vụ chi tiết tốt, nó không phải là ngôn ngữ kịch bản như bash hay ant, nó khá là tuyên bố - bạn nói - tôi cần một cuộc chiến, hoặc một cái tai, và bạn có được nó. Tuy nhiên, nếu bạn cần tùy chỉnh cách chiến tranh hoặc tai sẽ trông như thế nào bên trong, bạn có một vấn đề. Nó chỉ không phải là thủ tục như kiến, mà là khai báo. Điều này có một số ưu điểm vào đầu, và có thể có rất nhiều khuyết điểm ở cuối.

Tôi đoán khái niệm ban đầu là có các plugin tốt, "chỉ hoạt động" nhưng thực tế sẽ khác nếu bạn làm những thứ không chuẩn.

Tuy nhiên, nếu bạn đặt đủ nỗ lực vào các poms của mình và một vài plugin tùy chỉnh, bạn sẽ có được môi trường xây dựng tốt hơn nhiều như ví dụ (tất nhiên phụ thuộc vào dự án của bạn, nhưng điều đó càng đúng với các dự án lớn hơn).



4

Một cách chung để sao chép các tệp tùy ý là sử dụng trừu tượng vận chuyển Maven Wagon . Nó có thể xử lý những điểm đến khác nhau qua các giao thức thích file, HTTP, FTP, SCPhoặc WebDAV.

Có một vài plugin cung cấp phương tiện để sao chép tệp thông qua việc sử dụng Wagon. Đáng chú ý nhất là:

  • Out-of-the-box Maven Triển khai Plugin

    deploy-filemục tiêu. Nó khá không linh hoạt nhưng có thể hoàn thành công việc:

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

    Bất lợi đáng kể khi sử dụng Maven Deploy Pluginlà nó được chỉ định để làm việc với kho lưu trữ Maven. Nó giả định cấu trúc và siêu dữ liệu cụ thể. Bạn có thể thấy rằng tệp được đặt bên dưới foo/bar/1.0/file-1.0.extvà tệp tổng kiểm tra được tạo. Không có cách nào xung quanh điều này.

  • Plugin Wagon Maven

    Sử dụng upload-singlemục tiêu :

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

    Việc sử dụng Wagon Maven Pluginđể sao chép là đơn giản và dường như là linh hoạt nhất.


Trong các ví dụ trên <url>có thể là bất kỳ giao thức được hỗ trợ. Xem danh sách các nhà cung cấp xe ngựa hiện có . Ví dụ

  • sao chép tập tin cục bộ: file:///copy/to
  • sao chép tập tin vào máy chủ từ xa đang chạy SSH:scp://host:22/copy/to


Các ví dụ trên vượt qua các tham số plugin trong dòng lệnh. Ngoài ra, các plugin có thể được cấu hình trực tiếp trong POM. Sau đó, việc gọi sẽ đơn giản là như thế mvn deploy:deploy-file@configured-execution-id. Hoặc nó có thể được ràng buộc với giai đoạn xây dựng cụ thể.


Xin lưu ý rằng đối với các giao thức muốn SCPhoạt động, bạn sẽ cần xác định tiện ích mở rộng trong POM:

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


Nếu đích bạn đang sao chép để yêu cầu xác thực, thông tin đăng nhập có thể được cung cấp thông qua Servercài đặt . repositoryId/ serverIdđược chuyển đến các plugin phải khớp với máy chủ được xác định trong cài đặt.


3

Tôi chỉ có thể giả sử rằng thuộc tính $ {project.server.config} của bạn là thứ được xác định tùy chỉnh và nằm ngoài bố cục thư mục chuẩn.

Nếu vậy, thì tôi sẽ sử dụng tác vụ sao chép.


Giả sử tôi cẩn thận đặt các tệp vào bố cục thư mục chuẩn. Maven có thể sao chép chúng vào mục tiêu nguyên trạng, không phải trong một zip / jar không?
Joshua Fox

2

Một cách khác là gói những thứ này vào một vật phẩm bằng cách sử dụng plugin lắp ráp. Sau đó, bạn có thể sử dụng plugin phụ thuộc để giải nén các tệp này ở nơi bạn muốn. Ngoài ra còn có các mục tiêu sao chép trong plugin phụ thuộc để sao chép các tạo phẩm.


1

Tôi đã có thể ghép một số nguồn khác nhau cho câu trả lời này:

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

Từ ~/.m2/settings.xml:

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

Sau đó chạy lệnh: (-X là để gỡ lỗi)

mvn -X upload:upload


-1

Để tóm tắt một số câu trả lời hay ở trên: Maven được thiết kế để xây dựng các mô-đun và sao chép kết quả vào kho lưu trữ Maven. Mọi sao chép mô-đun vào thư mục đầu vào triển khai / cài đặt phải được thực hiện bên ngoài ngữ cảnh của chức năng cốt lõi của Maven, ví dụ như với lệnh sao chép Ant / Maven .


Ant thuộc về chức năng cốt lõi của Maven và Wagon cũng vậy (mặc dù plugin xung quanh nó không phải là plugin lõi Maven chính thức).
GeroldBroser phục hồi Monica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.