Kế thừa phiên bản dự án Maven - tôi có phải chỉ định phiên bản gốc không?


188

Tôi có hai dự án: Dự án mẹ: A, Dự án phụ: B

A / pom.xml:

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>

Và trong B / pom.xml, tôi có:

    <parent>
        <groupId>com.dummy.bla</groupId>
        <artifactId>parent</artifactId>
        <version>0.1-SNAPSHOT</version>     
    </parent>

    <groupId>com.dummy.bla.sub</groupId>
    <artifactId>kid</artifactId>

Tôi muốn B kế thừa phiên bản từ cha mẹ, vì vậy nơi duy nhất trong trường hợp tôi cần đặt 0.1-SNAPSHOTA/pom.xml. Nhưng nếu tôi loại bỏ <version>0.1-SNAPSHOT</version>từ B/pom.xmlbên dưới phần cha mẹ, maven phàn nàn về phiên bản còn thiếu cho phụ huynh.

Có cách nào tôi chỉ có thể sử dụng ${project.version}hoặc một cái gì đó như thế này để tránh có 01.-SNAPSHOTtrong cả hai poms không?


4
Bạn sẽ phải chờ Maven 3.1 vì điều đó, tôi sợ.
Nhận thức



1
Các liên kết ở trên đã di chuyển. Trạng thái cuối cùng là các vấn đề "Đã đóng / Không sửa" .apache.org/jira/browse/MNG
624

Câu trả lời:


86

EDIT: Vì Maven 3.5.0 có một giải pháp hay cho việc sử dụng ${revision}trình giữ chỗ này. Xem câu trả lời của FrVaBe để biết chi tiết. Đối với các phiên bản Maven trước, xem câu trả lời ban đầu của tôi dưới đây.


Không, không có. Bạn luôn phải chỉ định phiên bản của cha mẹ. May mắn thay, nó được kế thừa như phiên bản của mô-đun, điều mong muốn trong hầu hết các trường hợp. Hơn nữa, khai báo phiên bản của phụ huynh này được Maven Release Plugin tự động xử lý, vì vậy - thực tế - không có vấn đề gì khi bạn có phiên bản ở 2 nơi miễn là bạn sử dụng Plugin phát hành Maven để phát hành hoặc chỉ trả lại các phiên bản.

Lưu ý rằng có một số trường hợp khi hành vi này thực sự khá OK và cho phép bạn linh hoạt hơn. Đôi khi bạn muốn sử dụng một số phiên bản của cha mẹ trước đó để kế thừa, tuy nhiên đó không phải là trường hợp chính.


3
Bây giờ bạn có thể sử dụng ${revision}trình giữ chỗ cho việc này. Xem câu trả lời của tôi ;-)
FrVaBe

2
Điều này đã hết hạn - kiểm tra câu trả lời của @ FrVaBe tại đây: stackoverflow.com/a/51969067/514483
cướp

@FrVaBe nếu chúng ta có cha mẹ lồng nhau với các phiên bản khác nhau thì sao? Chúng tôi không thể sử dụng một thuộc tính $ {revision} ở đó, điều đó là không đủ.
halil

@halil Câu hỏi là về việc kế thừa một phiên bản từ cha mẹ với mục tiêu có cùng một phiên bản trong hai hiện vật. Nếu bạn có cha mẹ khác nhau với các phiên bản khác nhau (trong hệ thống phân cấp thừa kế), bạn có thể sẽ không biến họ thành cùng một phiên bản. Do đó tôi không hoàn toàn hiểu bình luận.
FrVaBe

86

Maven không được thiết kế để hoạt động theo cách đó, nhưng một cách giải quyết tồn tại để đạt được mục tiêu này (có thể với các tác dụng phụ, bạn sẽ phải thử). Bí quyết là nói với dự án con tìm cha mẹ của nó thông qua đường dẫn tương đối của nó chứ không phải tọa độ maven thuần túy của nó và ngoài việc ngoại lệ số phiên bản trong một thuộc tính:

Phụ huynh

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>${global.version}</version>
<packaging>pom</packaging>

<properties>
   <!-- Unique entry point for version number management --> 
   <global.version>0.1-SNAPSHOT</global.version>
</properties>

Pom con

<parent>
   <groupId>com.dummy.bla</groupId>
   <artifactId>parent</artifactId>
   <version>${global.version}</version>
   <relativePath>..</relativePath>    
</parent>

<groupId>com.dummy.bla.sub</groupId>
<artifactId>kid</artifactId>

Tôi đã sử dụng mánh khóe đó trong một thời gian cho một dự án của mình, không có vấn đề cụ thể nào, ngoại trừ việc maven ghi lại rất nhiều cảnh báo khi bắt đầu xây dựng, điều này không thanh lịch lắm.

BIÊN TẬP

Có vẻ như maven 3.0.4 không cho phép cấu hình như vậy nữa.


2
vâng, tôi e rằng maven không được thiết kế để hoạt động theo cách đó, tốt hơn là cứ gắn bó với việc đưa các phiên bản vào tệp pom.xml phụ. maven phát hành plugin không thực sự quan tâm đến các phiên bản ở đó.
Shengjie

7
cho 3.0.5 hoạt động ok. bạn nên đặt <property> lên trên cùng.

7
Nó hoạt động trong 3.2.3. Vị trí của <property> không quan trọng. Bạn sẽ nhận được một cảnh báo mặc dù:'version' contains an expression but should be a constant.
kapex

4
Xin hãy cẩn thận với điều này. Điều này không hoạt động khi dự án của bạn đang được dự án khác tham chiếu. Tài sản sẽ không được giải quyết và sẽ được xử lý theo nghĩa đen (ví dụ $ {my.version}). Điều này sẽ dẫn đến thất bại khi giải quyết phụ thuộc.
spekdrum

2
Tôi cũng đã sử dụng điều này khá lâu rồi và nó hoạt động rất tốt (hiện tại với maven 3.3.9) cho một dự án đa mô-đun. Tuy nhiên, ngay khi dự án của bạn trở thành một sự phụ thuộc của một dự án khác, mọi thứ sẽ trở nên khó khăn. Tôi thực sự đề nghị chấp nhận đề xuất được đề xuất bởi @pay bên dưới.
khéo léo

80

Cách dễ nhất để cập nhật phiên bản IMO:

$ mvn versions:set -DgenerateBackupPoms=false

(làm điều đó trong thư mục pom gốc / cha mẹ của bạn).

POM của bạn được phân tích cú pháp và bạn được hỏi nên đặt phiên bản nào.


17
Bạn cũng có thể thêm -DnewVersion = {versionToBeUpdated} để tránh nhập nó một cách tương tác.
Mukesh

1
Tôi nghĩ rằng đây là câu trả lời tốt nhất, nó tự động thay đổi phiên bản mà không phá vỡ các tiểu dự án (mà bạn sẽ không thể tham khảo nếu không có cha mẹ).
Tarek

Vâng Đây là câu trả lời. 🙌
aaiezza

Nếu phiên bản pom con và cha mẹ ban đầu khác nhau, trước tiên hãy cập nhật chúng cho phù hợp, mvn versions:update-child-modules nếu không tất cả phiên bản pom mô-đun con sẽ bị bỏ qua.
Gautam Tadigoppula

74

Vì Maven 3.5.0, bạn có thể sử dụng ${revision}trình giữ chỗ cho điều đó. Việc sử dụng được ghi lại ở đây: Phiên bản thân thiện với Maven CI .

Nói tóm lại, pom cha trông như thế này (trích từ tài liệu của Apache):

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.apache</groupId>
    <artifactId>apache</artifactId>
    <version>18</version>
  </parent>
  <groupId>org.apache.maven.ci</groupId>
  <artifactId>ci-parent</artifactId>
  <name>First CI Friendly</name>
  <version>${revision}</version>
  ...
  <properties>
    <revision>1.0.0-SNAPSHOT</revision>
  </properties>
  <modules>
    <module>child1</module>
    ..
  </modules>
</project>

và đứa trẻ như thế này

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.apache.maven.ci</groupId>
    <artifactId>ci-parent</artifactId>
    <version>${revision}</version>
  </parent>
  <groupId>org.apache.maven.ci</groupId>
  <artifactId>ci-child</artifactId>
   ...
</project>

Bạn cũng phải sử dụng Plugin Flatten Maven để tạo tài liệu pom với số phiên bản chuyên dụng đi kèm để triển khai. HowTo được ghi lại trong tài liệu được liên kết.

Ngoài ra @khmarbaise đã viết một bài đăng tuyệt vời về tính năng này: Maven: POM Files không có phiên bản trong đó?


Tôi đã cấu hình dự án của mình giống như bạn mô tả, nhưng không có "Flatten Maven Plugin" và nó dường như hoạt động như mong đợi, điều này có khả thi không? Ngoài ra tôi có một lỗi với maven 3.2.1, nhưng maven 3.3.9+ dường như hoạt động tốt.
Tối đa

@Max Nó phụ thuộc vào những gì bạn định nghĩa là "làm việc như mong đợi". Tôi đoán việc xây dựng sẽ vượt qua nhưng cài đặt / triển khai vào kho lưu trữ có thể sẽ không có ý tưởng hay vì không có số phiên bản trong pom con mà chỉ có một trình giữ chỗ (xem tài liệu )
FrVaBe

Tôi sử dụng <version> $ {revision} </ version> trong cha mẹ với thuộc tính mặc định (<property> <version> 0.1-default </ version> </ property>. Các poms con cũng sử dụng <version> $ {revision} < / version>. Tôi sử dụng "mvn clean install -Drevision = 0.1. $ {tre.buildNumber}". Khi tôi quét nhật ký triển khai, mọi thứ được đặt thành 0.1.820 và 0.1 - mặc định không có trong nhật ký (820 là buildNumber). Khi tôi quét tệp kết quả, tôi thấy "Phiên bản triển khai: 0.1.820" trong tệp kê khai và "phiên bản = 0.1.820" trong tệp pom.properies. Bản thân tệp pom có ​​<phiên bản> $ {sửa đổi} </ phiên bản>. Vì vậy, tôi nghĩ rằng nó ổn?
Tối đa

1
@Max Hãy thử giải quyết một jar trong đó phiên bản nằm ${revision} trong pom (trong kho lưu trữ maven) dưới dạng phụ thuộc trong dự án khác. Tôi không nghĩ rằng điều này sẽ làm việc.
FrVaBe

Điều này rất hữu ích trừ khi tôi phát hành. Điều đó thay thế ${revision}trong thẻ phiên bản bằng phiên bản mới
Mike D

21

Như Yanflea đã đề cập, có một cách để đi xung quanh điều này.

Trong Maven 3.5.0, bạn có thể sử dụng cách chuyển phiên bản sau từ dự án mẹ:

Phụ huynh POM.xml

<project ...>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mydomain</groupId>
    <artifactId>myprojectparent</artifactId>
    <packaging>pom</packaging>
    <version>${myversion}</version>
    <name>MyProjectParent</name>

    <properties>
        <myversion>0.1-SNAPSHOT</myversion>
    </properties>

    <modules>
        <module>modulefolder</module>
    </modules>
    ...
</project>

Mô-đun POM.xml

<project ...>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.mydomain</groupId>
        <artifactId>myprojectmodule</artifactId>
        <version>${myversion}</version> <!-- This still needs to be set, but you can use properties from parent -->
    </parent>

    <groupId>se.car_o_liner</groupId>
    <artifactId>vinno</artifactId>
    <packaging>war</packaging>
    <name>Vinno</name>
    <!-- Note that there's no version specified; it's inherited from parent -->
    ...
</project>

Bạn có thể tự do thay đổi myversionthành bất cứ điều gì bạn muốn mà không phải là tài sản dành riêng.


3
Khi tham chiếu một mô-đun từ một dự án khác, Maven không giải quyết thuộc tính. Điều đó có bình thường không?
LeoLozes

Tôi tin rằng câu hỏi đó có thể xứng đáng với mục riêng của nó và không được bình luận như thế này. Không thấy mã của bạn, tôi chỉ có thể đoán.
eFox

@LeoLozes Bạn đã giải quyết vấn đề của mình (mô đun điều chỉnh từ dự án khác)?
Morteza Malvandi

@MortezaMalvandi có! Câu trả lời của tôi ở phía dưới :)
LeoLozes

2
Maven 3.6.0 đưa ra cảnh báo cho cấu hình này: "Rất khuyến khích khắc phục những sự cố này vì chúng đe dọa sự ổn định của bản dựng của bạn." "Vì lý do này, các phiên bản Maven trong tương lai có thể không còn hỗ trợ xây dựng các dự án không đúng định dạng như vậy."
d2k2

17

Bạn cũng có thể sử dụng:

$ mvn release:update-versions -DdevelopmentVersion={version}

để cập nhật số phiên bản trong POM của bạn.


10

Câu trả lời của eFox đã làm việc cho một dự án duy nhất, nhưng không phải khi tôi đang tham chiếu một mô-đun từ một dự án khác (pom.xml vẫn được lưu trữ trong tôi .m2với thuộc tính thay vì phiên bản).

Tuy nhiên, nó hoạt động nếu bạn kết hợp nó với flatten-maven-plugin, vì nó tạo ra các poms với phiên bản chính xác, không phải thuộc tính.

Tùy chọn duy nhất tôi đã thay đổi trong định nghĩa trình cắm là outputDirectorymặc định, nó trống, nhưng tôi thích có nó hơn target, được đặt trong .gitignorecấu hình của tôi :

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>flatten-maven-plugin</artifactId>
   <version>1.0.1</version>
   <configuration>
      <updatePomFile>true</updatePomFile>
      <outputDirectory>target</outputDirectory>
   </configuration>
   <executions>
      <execution>
         <id>flatten</id>
         <phase>process-resources</phase>
         <goals>
            <goal>flatten</goal>
         </goals>
      </execution>
   </executions>
</plugin>

Cấu hình trình cắm đi trong tệp cha mẹ



0
<parent>
    <groupId>com.dummy.bla</groupId>
    <artifactId>parent</artifactId>
    <version>0.1-SNAPSHOT</version>     
 </parent>

 <groupId>com.dummy.bla.sub</groupId>
 <artifactId>kid</artifactId>

Bạn có nghĩa là bạn muốn xóa phiên bản khỏi khối cha mẹ của B, tôi nghĩ bạn không thể làm điều đó, groupId, artifactId và phiên bản đã chỉ định tọa độ pom của cha mẹ, những gì bạn có thể bỏ qua là phiên bản của con.

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.