Bagaimana cara menentukan lebar organisasi distributionManagement maven?

110

Saya mencoba mencari cara untuk mengatur banyak (sekitar 50+) proyek maven2, sehingga mereka dapat menyebarkannya ke dalam repositori nexus pusat. Saat menggunakan mvn deploytujuan, seseorang perlu menentukan target di tag distributionManagement seperti ini:

<distributionManagement>
   <repository>
      <id>nexus-site</id>
        <url>http://central_nexus/server</url>
   </repository>
</distributionManagement>

Sekarang, saya tidak ingin setiap pom.xml (dari 50+ itu) mengandung blok ini berulang kali. Meskipun pertama saya adalah settings.xmlfile, tetapi tampaknya tidak mungkin (dengan desain) untuk mendefinisikannya di sana. Jadi, pertanyaan pertama adalah, mengapa demikian? Jika memungkinkan, saya dapat menentukannya di settings.xml dalam distribusi maven2, yang dapat didistribusikan ke semua pengembang.

Satu-satunya solusi yang mungkin saya temukan adalah membuat proyek master-pom seluruh organisasi, yang berisi pengaturan ini, dan membuat semua pom.xml lainnya bergantung pada master-pom melalui <parent>tag. Tapi ini terlihat agak aneh dalam build multi-modul:

- master configuration POM (pm)
- Project 1 parent pom (p1 with module 1 and module 2 as modules)
    - Project 1 module pom (with pm as parent)
    - Project 2 module pom (with pm as parent)

Biasanya saya membaca di semua dokumentasi bahwa modul pom harus menggunakan pom induk, bukan yang berbeda. Tapi setelah membaca website maven tentang Warisan v. Agregasi tertulis bahwa itu memang mungkin.

Satu masalah yang saya temukan adalah dengan pembuatan situs maven, yang tampaknya memiliki masalah dengan pengaturan ini (modul tidak terhubung dengan benar jika mereka tidak memiliki referensi balik langsung)

Jadi, apakah ini pendekatan yang valid? Adakah solusi lain yang lebih jelas dan sederhana untuk masalah ini?

mglauche.dll
sumber
5
@OhadR: Mereka hanya menulis bagaimana menulisnya dalam satu proyek. Intinya adalah saya tidak ingin menggandakannya sekitar 500 kali ...
mglauche
1
saya melihat. poin diambil. sehingga yang menjawab berkata, Anda dapat memiliki pom utama untuk proyek, yang akan berisi 'distribMngmnt' ...
OhadR

Jawaban:

144

Solusi terbaik untuk ini adalah membuat proyek file induk pom sederhana (dengan pengemasan 'pom') secara umum untuk semua proyek dari organisasi Anda.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>your.company</groupId>
    <artifactId>company-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <distributionManagement>
        <repository>
            <id>nexus-site</id>
            <url>http://central_nexus/server</url>
        </repository>
    </distributionManagement>

</project>

Ini dapat dibangun, dirilis, dan diterapkan ke nexus lokal Anda sehingga setiap orang memiliki akses ke artefaknya.

Sekarang untuk semua proyek yang ingin Anda gunakan, cukup sertakan bagian ini:

<parent>
  <groupId>your.company</groupId>
  <artifactId>company-parent</artifactId>
  <version>1.0.0</version>
</parent>

Solusi ini akan memungkinkan Anda dengan mudah menambahkan hal umum lainnya ke semua proyek perusahaan Anda. Misalnya jika Anda ingin menstandarkan penggunaan JUnit Anda ke versi tertentu, ini akan menjadi tempat yang tepat untuk itu.

Jika Anda memiliki proyek yang menggunakan struktur multi-modul yang memiliki induknya sendiri, Maven juga mendukung pewarisan rantai sehingga sangat dapat diterima untuk membuat file pom induk proyek Anda merujuk ke pom induk perusahaan Anda dan membuat modul anak proyek bahkan tidak menyadari keberadaan Anda. induk perusahaan.

Saya melihat dari contoh struktur proyek Anda bahwa Anda mencoba untuk menempatkan proyek induk Anda pada tingkat yang sama dengan pom aggregator Anda. Jika proyek Anda membutuhkan induknya sendiri, pendekatan terbaik yang saya temukan adalah menyertakan induk pada tingkat yang sama dengan modul lainnya dan memiliki file pom.xml aggregator di root tempat semua direktori modul Anda berada.

- pom.xml (aggregator)
    - project-parent
    - project-module1
    - project-module2

Apa yang Anda lakukan dengan struktur ini adalah menyertakan modul induk Anda di agregator dan membangun semuanya dengan a mvn installdari direktori root.

Kami menggunakan solusi yang tepat ini di organisasi saya dan telah teruji oleh waktu dan bekerja dengan cukup baik bagi kami.

Jesse Webb
sumber
Berikut adalah jawaban lain di mana saya menjelaskan warisan proyek secara lebih rinci dan bagaimana mengelola kompleksitas warisan itu, maafkan permainan kata-katanya. ;) stackoverflow.com/questions/6347913
Jesse Webb
7
Hanya catatan kecil: untuk alasan mengapa induk perusahaan adalah solusi terbaik, lihat diskusi Tidak dapat menentukan distributionManagement di settings.xml dari daftar pengguna Maven.
Premek Brada
Dalam model konsultasi klasik, di mana "klien memiliki kode", tim pengembangan saya perlu mengerjakan proyek di luar situs dan kemudian mengambil kode terbaru ke situs klien dan membuatnya lagi. Dalam situasi saya, bekerja dengan proyek multi-modul, jika saya mereferensikan POM perusahaan di POM induk proyek, saya harus memperbarui referensi itu untuk menunjuk ke POM perusahaan klien. Saya lebih suka berusaha untuk mempertahankan semua pengaturan khusus lingkungan di settings.xml jika saya dapat membantu. Apa pendekatan yang direkomendasikan untuk situasi saya?
Pengguna Web
2
@WebUser Masalah Anda terdengar lebih seperti situasi di mana Anda membutuhkan nilai yang berbeda dalam file POM Anda sebagai lawan dari apa jawaban ini alamat: menghindari pengaturan duplikat di beberapa modul. Saya pikir Anda harus mencoba menyuntikkan properti melalui file settings.xml . Jika itu tidak membantu Anda, ajukan pertanyaan baru di sini di SO, tautkan ke sini, dan saya akan mencoba membantu Anda lebih lanjut.
Jesse Webb
Terima kasih @JesseWebb Saya akhirnya mencobanya dan berguna untuk mengabstraksi nilai-nilai tersebut dari POM untuk situasi yang saya jelaskan. Untuk kebutuhan saya, saya menambahkan properti yang relevan di bawah profil aktif dan yang diselesaikan di Badan POM.
Pengguna Web
36

Tidak perlu POM orang tua.

Anda dapat menghilangkan bagian distributionManagement sepenuhnya di pom Anda dan menyetelnya di server build Anda atau di settings.xml.

Untuk melakukannya di server build, cukup teruskan ke mvnperintah:

-DaltSnapshotDeploymentRepository=snapshots::default::https://YOUR_NEXUS_URL/snapshots
-DaltReleaseDeploymentRepository=releases::default::https://YOUR_NEXUS_URL/releases

Lihat https://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.html untuk detail opsi mana yang dapat disetel.

Ini juga memungkinkan untuk mengatur ini di settings.xml.

Cukup buat profil di sana yang diaktifkan dan berisi properti.

Contoh settings.xml:

<settings>
[...]
  <profiles>
    <profile>
      <id>nexus</id>
      <properties>
        <altSnapshotDeploymentRepository>snapshots::default::https://YOUR_NEXUS_URL/snapshots</altSnapshotDeploymentRepository>
        <altReleaseDeploymentRepository>releases::default::https://YOUR_NEXUS_URL/releases</altReleaseDeploymentRepository>
      </properties>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>nexus</activeProfile>
  </activeProfiles>

</settings>

Pastikan bahwa kredensial untuk "snapshots" dan "release" ada di <servers>bagian settings.xml Anda

Properti altSnapshotDeploymentRepository dan altReleaseDeploymentRepository diperkenalkan dengan maven-deploy-plugin versi 2.8. Versi yang lebih lama akan gagal dengan pesan kesalahan

Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter

Untuk memperbaikinya, Anda dapat menerapkan versi plugin yang lebih baru:

        <build>
          <pluginManagement>
            <plugins>
              <plugin>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8</version>
              </plugin>
            </plugins>
          </pluginManagement>
        </build>
Michael Wyraz
sumber
Saya terus mencoba solusi ini tetapi hanya properti altDeploymentRepository yang berfungsi. altReleaseDeploymentRepository dan altSnapshotDeploymentRepository tidak dikenali dan saya mendapatkan error ini: Deployment gagal: elemen repositori tidak ditentukan di POM di dalam elemen distributionManagement atau di -DaltDeploymentRepository = id :: layout :: url paramete. Saran apa pun akan membantu. Terima kasih
Shabirmean
@Shabirmean Alasannya adalah versi plugin penerapan yang terlalu lama. Saya telah memperpanjang jawaban saya dengan sebuah solusi.
Michael Wyraz
Ya, saya pikir itu. Terima kasih banyak :)
Shabirmean