Maven ile dosya kopyalamak için en iyi uygulamalar


194

Maven2 kullanarak dev ortamından dev-server dizinine kopyalamak istediğim yapılandırma dosyaları ve çeşitli belgelerim var. Garip bir şekilde Maven bu görevde güçlü görünmüyor.

Seçeneklerden bazıları:

  • Maven'de basit bir kopyalama görevi kullanın
<copy file="src/main/resources/config.properties" tofile="${project.server.config}/config.properties"/>
  • Ant kopyasını yürütmek için Ant eklentisini kullanın .

    • Tipi bir objeyi Construct zip genellikle tipi olan POM "ana" eser yanında, kavanoz , daha sonra paketten hedef dizine deposundan gelen obje.

    • maven kaynakları eklentisi, aşağıda belirtildiği gibi.

    • Maven Assembly eklentisi - ancak işleri basitçe ve "geleneksel olarak" yapmak istediğimde, bu çok fazla manuel tanım gerektiriyor gibi görünüyor.

    • Bu sayfa , kopyalama yapmak için nasıl bir eklenti oluşturulacağını gösterir!

    • aşağıda belirtildiği gibi maven-upload eklentisi.

    • aşağıda belirtildiği gibi kopya ile maven-bağımlılık-eklentisi .


Tüm bunlar gereksiz yere ad hoc görünüyor: Maven, bu standart görevleri sorunsuz ve zahmetsizce yerine getirmede mükemmel.

Herhangi bir tavsiye?


2
Maven, aşamaları olan bir yaşam döngüsü fikri etrafında inşa edilir, rastgele dosyaları uzak sunucu görevine kopyala gerçekten buna uymaz. Projenizi daima bir bütün olarak düşünün.
André

3
“Bütün bunlar gereksiz yere ad hoc görünüyor: Maven, bu standart görevleri zahmetsizce ve zahmetsizce yapmakta başarılı olmalı.” Yaptığınız şey standart bir görev değil. Eseriniz bir savaş / kulak olsaydı, bu kargo eklentisini kullanmak kadar basit olurdu (cargo.codehaus.org/Maven2+plugin#Maven2plugin-get…). Açıkladığınız şey, standart java uygulama kapsayıcısı dağıtımlarına değil, dağıtımları nasıl yaptığınıza çok özel geliyor. Maven, gerçek zamanlı sunuculara dağıtım zamanı etkinliklerini gerçekleştirecek şekilde tasarlanmamıştır; daha fazla etkinlik / geliştirme etkinliği oluşturmaya yöneliktir.
whaley

67
@ André: Bu tartışmayı tekrar tekrar duyuyorum, ama üzgünüm, bu BS. Projeyi bir bütün olarak düşünmekle ilgili yanlış bir şey yok, ancak herhangi bir iyi inşa sisteminin bir kısmı, dosyaları kopyalamak gibi X görevini doğrudan ileriye götürmeme izin veren işlevsellik olmalıdır ve Maven bunu yapamaz. Son zamanlarda kod oluşturma-kod paradigmasını (Gradle, SBT veya Buildr gibi) kucaklayan birçok projenin ortaya çıkmasının bir nedeni var.
Matthias

Eserleri oluşturmak için pom.xml ve belirli bir eseri dağıtmak için başka bir pom.xml olmasını öneriyorum .
Thorbjørn Ravn Andersen

Yukarıdaki tüm öneriler, belirli bir dosyayı farklı bir proje / yapıdan bir maven projesine kopyalamama izin vermiyor gibi görünüyor. Bir kavanoz haline gelen bir eserde src / main / klasör altında bazı dosyalar var ve bağımlılık kopyasını maven eklentisini kullanmayı denedim, ancak hangi dosyaları kopyalamak istediğimi söylemenin bir yolunu bulamadım ve tüm kavanozu aldım her zaman montaj dosyasında dosya. Buradaki diğer tüm öneriler, kaynaklar gibi, proje içindeki kaynaklar yerine bir eser belirtmeme izin vermiyor gibi görünüyor
Alexandre Thenorio

Yanıtlar:


120

Antrun eklentisinden uzak durmayın. Bazı insanlar Ant ve Maven'in karşıt olduklarını düşünmeye eğilimli oldukları için değiller. Kaçınılmaz bir kerelik özelleştirme yapmanız gerekiyorsa kopyalama görevini kullanın:

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

Bu soruyu cevaplarken, sorduğunuz soruların ayrıntılarına odaklanıyorum. Bir dosyayı nasıl kopyalarım? Soru ve değişken adı beni aşağıdaki gibi daha büyük sorulara yönlendiriyor: "Sunucu sağlama ile başa çıkmanın daha iyi bir yolu var mı?" Konuşlandırılabilir yapı oluşturmak için Maven'i bir yapı sistemi olarak kullanın, ardından bu özelleştirmeleri ayrı modüllerde veya tamamen başka bir yerde gerçekleştirin. Oluşturma ortamınızın biraz daha fazlasını paylaştıysanız, daha iyi bir yol olabilir - birkaç sunucu sağlamak için eklentiler vardır. Sunucunun kökünde paketi açılmış bir montaj ekleyebilir misiniz? Hangi sunucuyu kullanıyorsunuz?

Yine, eminim daha iyi bir yol var.


Görev tanımlayıcı artık kullanımdan kaldırıldı mı?
Matt

3
@Matt Evet, taskparametre artık kullanımdan kaldırıldı ( Antrun Eklentisi ). Bunun targetyerine kullanmalısınız (1.5'ten beri). Ne yazık ki bunu karıştıran örnekler var; örneğin targetparametre ve version<1.5.
cuh

Bu kabul edilen cevap nasıl olabilir? Kesinlikle kopyayı basitleştirmek için bir değişiklik isteği olmalıdır.
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>

Teşekkürler @Peter, bu yararlı oldu. Şimdi antrun yerine resources-plugin copy-resources hedefini kullanıyorum. İkincisi aslında tanımlamak çok daha basit ve sezgisel, ancak tüm Maven özel özelliklerini (<properties> bölümünde tanımlanan) antrun'a geçirmek için (sürüm 1.3) alamadım, bu yüzden kaynaklar eklentisine geçtim.
Cornel Masson

2
Kaynak eklentisinin atlama yapılandırması olmadığını anlayana kadar bunun doğru cevap olduğunu düşünürdüm. Antrun gidilecek yoldur.
Mike Post

Atlama profili oluşturmak zor olmamalı. Antrun kullanmadım, bu yüzden hangisinin daha kolay / daha iyi olduğunu söyleyemem
Vivek Chavda

41

Bir dosyayı kopyalamak için şunu kullanın:

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

Klasörü alt klasörlerle kopyalamak için bir sonraki yapılandırmayı kullanın:

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

Maven filtreleme dize enterpolasyonu ifade eder, bu yüzden değişkenleri <filtering>kullanan komut dosyası dosyalarında istenmeyen değişiklikleri önlemek için atlamak istiyorum ${...}.
Gerold Broser

20

Maven bağımlılık eklentisi karınca görevleri ile okşamak bana çok zaman kazandırdı:

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

Bağımlılık: kopya documentend ve açmak gibi daha kullanışlı hedefi vardır.


3
Ant'i yıllarca kullanmadım ve böyle basit bir şey için yapmaya başlamak istemiyorum. Bu cevap için teşekkürler.
Gustave

18

Basit bir kopyalama görevleri için copy-rename-maven-plugin önerebilirim . Basit ve kullanımı kolaydır:

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

Birden fazla dosya kopyalamak istiyorsanız, <sourceFile>...</destinationFile>parçayı

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

Ayrıca, gerekirse birden fazla aşamada birden fazla yürütme belirtebilirsiniz, ikinci amaç "yeniden adlandır" dır, bu da yapılandırmanın geri kalanı aynı kalırken söylediklerini yapar. Daha fazla kullanım örneği için Kullanım Sayfasına bakınız .

Not : Bu eklenti sadece dosyaları kopyalayabilir, dizinleri kopyalayamaz. (Bu sınırlamayı bulduğu için @ james.garriss'e teşekkürler.)


2
Bu eklentiyi beğenmeme rağmen, dizinleri kopyalayamaması şaşırtıcı.
james.garriss

3
@ james.garriss Bu sınırlamanın farkında değildim ama maalesef haklısın. Bazı insanlar bunu kendileri bularak zamandan kurtarmak için bunu cevabımda düzenleyeceğim.
morten.c

7

Yukarıdaki karınca çözümü yapılandırmak en kolay, ama Atlassian maven-upload-eklentisi kullanarak şans oldu. İyi dokümanları bulamadım, işte nasıl kullanıyorum:

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

Yukarıda belirtilen "$ {jboss.host}" gibi değişkenler ~ / .m2 / settings.xml dosyamda tanımlanmıştır ve maven profilleri kullanılarak etkinleştirilmiştir. Bu çözüm JBoss ile sınırlı değil, bu sadece değişkenlerimi adlandırdım. Dev, test ve live için bir profilim var. Bu yüzden kulağımı test ortamında bir jboss örneğine yüklemek için yürütürüm:

mvn upload:upload -P test

Settings.xml dosyasındaki bir pasaj:

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

Notlar: Bu eklentiye sahip Atlassian maven repo burada: https://maven.atlassian.com/public/

Eklentinin sağladığı tüm özellikleri görmek için kaynakları indirmenizi ve içindeki belgelere bakmanızı öneririm.

'


5

Maven'in ince taneli görevleri yerine getirmesi iyi değildir, bash veya karınca gibi bir betik dili değildir, oldukça açıklayıcıdır - diyorsunuz - bir savaşa veya kulağa ihtiyacım var ve anlıyorsunuz. Bununla birlikte, savaşın veya kulağın içerideki gibi görünmesini özelleştirmeniz gerekiyorsa, bir sorununuz var. Sadece karınca gibi prosedürel değil, deklaratiftir. Bu başlangıçta bazı artıları var ve sonunda çok fazla eksileri olabilir.

Sanırım ilk konsept ince eklentilere sahip olmaktı, "sadece çalışıyor" ama standart olmayan şeyler yaparsanız gerçek farklıdır.

Bununla birlikte, pomslarınıza ve az sayıda özel eklentiye yeterince çaba harcarsanız, örneğin karınca gibi çok daha iyi bir yapı ortamı elde edersiniz (elbette projenize bağlıdır, ancak daha büyük projeler için giderek daha doğru hale gelir).


4

Copy-maven-plugin ile çok iyi bir deneyim yaşadım . Maven-resources-plugin ile karşılaştırıldığında çok daha kullanışlı ve özlü bir sözdizimine sahiptir.


8
Ne yazık ki, copy-maven-plugin maven 3.1.x ile uyumlu değil
Hakan


Bu eklentiyi unut ... Çatallarını ara
Kukeltje

4

Rastgele dosyaları kopyalamanın genel bir yolu Maven Wagon taşıma soyutlamasını kullanmaktır . Protokoller gibi aracılığıyla Çeşitli hedefler işleyebilir file, HTTP, FTP, SCPveya WebDAV.

Kullanarak dosyaları kopyalamak için olanaklar sağlayan birkaç eklenti vardır Wagon. En dikkat çekici olanlar:

  • Yeni Maven Deploy Eklentisi

    Orada deploy-filegolü. Oldukça esnek değil ama işi yapabilir:

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

    Kullanmanın önemli dezavantajı Maven Deploy Plugin, Maven depolarıyla çalışmak üzere tasarlanmasıdır. Belirli bir yapı ve meta veri olduğunu varsayar. Dosyanın altına yerleştirildiğini foo/bar/1.0/file-1.0.extve sağlama toplamı dosyalarının oluşturulduğunu görebilirsiniz. Etrafta yol bulunmuyor.

  • Wagon Maven Eklentisi

    upload-singleHedefi kullanın :

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

    Kullanımı Wagon Maven Pluginkopyalama için basittir ve çok yönlü olarak görünmektedir.


Yukarıdaki örneklerde <url> desteklenen herhangi bir protokol olabilir. Mevcut Vagon Sağlayıcıları listesine bakın . Örneğin

  • dosyayı yerel olarak kopyalama: file:///copy/to
  • çalışmakta olan uzak ana bilgisayara dosya kopyalanıyor SSH :scp://host:22/copy/to


Yukarıdaki örnekler eklenti parametrelerini komut satırına geçirir. Alternatif olarak, eklentiler doğrudanPOM . O zaman çağırma basitçe olacaktır mvn deploy:deploy-file@configured-execution-id. Veya belirli bir yapım aşamasına bağlanabilir.


SCPÇalışmak gibi protokoller için, aşağıdakilerinde bir uzantı tanımlamanız gerekeceğini lütfen unutmayın POM:

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


Kopyaladığınız hedef kimlik doğrulaması gerektiriyorsa, kimlik bilgileri Serverayarlar aracılığıyla sağlanabilir . repositoryId/ serverIdeklentilerine iletilen ayarlarda tanımlanan sunucu ile eşleşmelidir.


3

Yalnızca $ {project.server.config} özelliğinizin özel olarak tanımlanmış ve standart dizin düzeninin dışında olduğunu varsayabilirim.

Öyleyse, kopyalama görevini kullanırdım.


Diyelim ki dosyaları standart dizin düzenine koymaya özen gösteriyorum. Maven onları bir zip / kavanozda değil, olduğu gibi hedefe kopyalayabilir mi?
Joshua Fox

2

Başka bir yol, montaj eklentisini kullanarak bunları bir yapay yapıya toplamaktır. Sonra bu dosyaları istediğiniz yerde açmak için bağımlılık eklentisini kullanabilirsiniz. Bağımlılık eklentisinde yapay nesneleri kopyalamak için kopyalama hedefleri de vardır.


1

Bu cevap için bir dizi farklı kaynağı bir araya getirebildim:

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

Gönderen ~/.m2/settings.xml:

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

Sonra komutu çalıştırın: (-X hata ayıklama içindir)

mvn -X upload:upload


-1

Yukarıdaki bazı iyi cevapları özetlemek gerekirse: Maven , modüller oluşturmak ve sonuçları bir Maven deposuna kopyalamak için tasarlanmıştır. Modüllerin bir dağıtım / yükleyici-giriş dizinine kopyalanması, Maven'in temel işlevselliği bağlamında, örneğin Ant / Maven copy komutuyla yapılmalıdır .


Ant, Maven'in temel işlevselliğine aittir ve Wagon da (etrafındaki eklenti resmi bir Maven çekirdek eklentisi olmasa da).
Gerold Broser
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.