Versiyon kodunu maven pom.xml dosyasından alın


256

Koddaki maven's pom.xml'den sürüm numarasını almanın en basit yolu nedir, yani programlı olarak?

Yanıtlar:


264

Java kullandığınızı varsayarsak,

  1. Dizininizde .properties(en yaygın olarak) bir dosya oluşturun src/main/resources(ancak 4. adımda başka bir yere bakmasını söyleyebilirsiniz).

  2. .propertiesProje sürümü için standart Maven özelliğini kullanarak dosyanızdaki bazı özelliklerin değerini ayarlayın : foo.bar=${project.version}

  3. Java kodunuzda, özellikler dosyasındaki değeri sınıfyolundan kaynak olarak yükleyin (bunun nasıl yapılacağına dair bol örnek için google, ancak işte yeni başlayanlar için bir örnek ).

  4. Maven'de kaynak filtrelemeyi etkinleştirin - bu Maven'in o dosyayı çıktı sınıflarınıza kopyalamasına ve özelliği bu yorumlama sırasında kaynağı çevirmesine neden olur. Burada bazı bilgiler bulabilirsiniz, ancak çoğunlukla bunu pom'unuzda yaparsınız:

    <İnşa>
      <Kaynakları>
        <Kaynak>
          <Dizin> src / main / resources </ dizin>
          <Filtreleme> true </ filtreleme>
        </ Kaynak>
      </ Kaynaklar>   
    </ Yapı>

Ayrıca gibi diğer standart özellikler alabilirsiniz project.name, project.description, kendi pom koymak ve hatta keyfi özellikler <properties>, Maven profillerle kombine vs. Kaynak filtreleme, size oluşturma zaman değişken yapı davranışını verebilir. Çalışma zamanında ile bir profil belirttiğinizde -PmyProfile, daha sonra derlemenizde görünebilecek özellikleri etkinleştirebilirsiniz.


2
Ben bir değişiklik Maven yapılandırma bu bir kod bulundu .
Wendel

7
src/main/resourcesİkili dosyalar da dahil olmak üzere bu dizinde bulunan tüm dosyaları işleyebileceğinden, doğrudan filtrelemeyi kullanmaya dikkat edin . Öngörülemeyen davranışlardan kaçınmak için src/main/resources-filtered, burada önerildiği gibi bir dizine filtre uygulamak daha iyidir . Her neyse, bu güzel numara için teşekkürler!
SiZiOUS

1
Gerçek modeli elde etmek için MavenXppReader'ı kullanarak aşağıdaki cevap gerçekten yararlıdır, çünkü değeri bulmak için hiçbir şey çalıştırması gerekmez. Herhangi bir şey yapılmadan önce sürümü bilmeniz gereken durumlarda aşağıdaki cevaplara bakın; Gradle, kullanıma alınmış bir maven projesinin hangi versiyona sahip olduğunu bilmem için bana çok yardımcı oldu, bu yüzden önceden çıkış kavanoz konumunu biliyordum.
Ajax

92

Kabul edilen yanıt, bir sürüm numarasını statik olarak bir uygulamaya almak için en iyi ve en kararlı yol olabilir , ancak aslında asıl soruyu cevaplamaz: Artefaktın sürüm numarasını pom.xml'den nasıl alabilirim? Böylece, çalışma zamanı sırasında dinamik olarak nasıl yapılacağını gösteren bir alternatif sunmak istiyorum :

Maven'in kendisini kullanabilirsiniz. Daha kesin olmak gerekirse bir Maven kütüphanesi kullanabilirsiniz.

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-model</artifactId>
  <version>3.3.9</version>
</dependency>

Ve sonra Java'da böyle bir şey yapın:

package de.scrum_master.app;

import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.FileReader;
import java.io.IOException;

public class Application {
    public static void main(String[] args) throws IOException, XmlPullParserException {
        MavenXpp3Reader reader = new MavenXpp3Reader();
        Model model = reader.read(new FileReader("pom.xml"));
        System.out.println(model.getId());
        System.out.println(model.getGroupId());
        System.out.println(model.getArtifactId());
        System.out.println(model.getVersion());
    }
}

Konsol günlüğü aşağıdaki gibidir:

de.scrum-master.stackoverflow:my-artifact:jar:1.0-SNAPSHOT
de.scrum-master.stackoverflow
my-artifact
1.0-SNAPSHOT

2017-10-31 Güncellemesi: Simon Sobisch'in takip sorusunu cevaplamak için örneği şu şekilde değiştirdim:

package de.scrum_master.app;

import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Application {
  public static void main(String[] args) throws IOException, XmlPullParserException {
    MavenXpp3Reader reader = new MavenXpp3Reader();
    Model model;
    if ((new File("pom.xml")).exists())
      model = reader.read(new FileReader("pom.xml"));
    else
      model = reader.read(
        new InputStreamReader(
          Application.class.getResourceAsStream(
            "/META-INF/maven/de.scrum-master.stackoverflow/aspectj-introduce-method/pom.xml"
          )
        )
      );
    System.out.println(model.getId());
    System.out.println(model.getGroupId());
    System.out.println(model.getArtifactId());
    System.out.println(model.getVersion());
  }
}

1
Bu ne kullanın neredeyse aynıdır ve tutulma başlatıldığında cezası çalışır, ancak normal başladı vermediğinde packagemaven-montaj-eklentisi ile paketlenmiş zaman d kavanoz (bağımlılık sınıfları entegre edilmemiş) ve çalışmıyor jar-with-dependenciesben olsun a java.io.FileNotFoundException: pom.xml(son kavanozda olduğu gibi META-INF/maven/my.package/myapp/pom.xml) - bunun nasıl çözüleceğine dair ipuçları var mı?
Simon Sobisch

1
Çözümüm geliştirme ortamlarında, örneğin IDE veya konsoldan başlatılan testlerde veya araçlarda kullanıldığında dinamik olarak çalışmak anlamına geliyor. Bu soruya kabul edilen cevap, sürüm numarasını statik olarak eserlerinize paketlemenin çeşitli yollarını gösterir. Pom.xml'in JAR'lar içinde mevcut olacağını varsaymıyordum. Senin için orada olması güzel. Belki sadece dosya okuyucuyu açarken yolu ayarlayabilir ve belki de sınıf yükleyici durumuna bağlı hale getirebilirsiniz. Kendim için denemek zorunda kalacağım. Bu işe yaramazsa takip soruları sormaktan çekinmeyin.
kriegaex

2
Merhaba @SimonSobisch, istediğimi nasıl yapacağını göstermek için cevabımı güncelledim. Ama sadece hızlı ve kirli yaptım gerçeğinin farkında olun, özellikle iç içe inşaatçılar ile kodu sevmiyorum.
kriegaex

75

Paketlenmiş eserler META-INF/maven/${groupId}/${artifactId}/pom.propertiesiçeriğe benzeyen bir dosya içerir :

#Generated by Maven
#Sun Feb 21 23:38:24 GMT 2010
version=2.5
groupId=commons-lang
artifactId=commons-lang

Birçok uygulama bu dosyayı uygulama / jar sürümünü çalışma zamanında okumak için kullanır, sıfır kurulum gerekir.

Yukarıdaki yaklaşımla ilgili tek sorun, bu dosyanın (şu anda) packagefaz sırasında üretilmesidir ve bu nedenle testler vb. Sırasında mevcut olmayacaktır (bunu değiştirmek için bir Jira sorunu vardır, bkz. MJAR-76 ). Bu sizin için bir sorunsa, Alex'in tarif ettiği yaklaşım gitmenin yoludur.


10
özellikleri okuyan bir örnek arayan insanlar için, bu yazı çeşitli yöntemlerden geçer - javablog.fr/…
chrismarx

43

Maven kullanarak uygulama sürüm numaranızı görüntülemenin kolay yolunda açıklanan yöntem de vardır :

Bunu pom.xml'e ekle

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>test.App</mainClass>
            <addDefaultImplementationEntries>
              true
            </addDefaultImplementationEntries>
          </manifest>
        </archive>
      </configuration>
    </plugin>
  </plugins>
</build>

Sonra şunu kullanın:

App.class.getPackage().getImplementationVersion()

Bu yöntemi daha basit buldum.


18
-1 - Bu çözüm benim için işe yaramadı; değeri getImplementationVersion()oldu null. (maven sürüm 3.0.4)
Jesse Webb

7
faza bağlı olarak ... sadece artefakt paketlenirken çalışır, bu yüzden birim testlerde çalışmaz: - /
wikier

2
İçin .wareserler, kullanmayı unutmayın maven-war-pluginyerinemaven-jar-plugin
cs_pupil

Benim için bu Tomcat 8'de çalışıyor , ancak Tomcat 7'de çalışmıyor ( getImplementationVersion()null döndürür).
Alfonso Nishikawa

19

Kavanoz veya savaş gibi mvn ambalaj kullanıyorsanız, şunları kullanın:

getClass().getPackage().getImplementationVersion()

Arşivde oluşturulan META-INF / MANIFEST.MF (pom.xml sürümüne ayarlanan) bir özelliği "Uygulama-Sürüm" okur.


19

@Kieste'nin yayınladığı şeyi tamamlamak için, Spring-boot kullanıyorsanız Maven'in kodunuzda bilgi oluşturmasının en iyi yolu olduğunu düşünüyorum: http://docs.spring.io/spring-boot/ docs / current / reference / htmlsingle / # production-ready-application-info çok faydalıdır.

Sadece etkinleştirmek eyleyicilere gerekir ve gereken özellikler eklemek sizin application.propertiesveyaapplication.yml

Automatic property expansion using Maven

You can automatically expand info properties from the Maven project using resource filtering. If you use the spring-boot-starter-parent you can then refer to your Maven project properties via @..@ placeholders, e.g.

project.artifactId=myproject
project.name=Demo
project.version=X.X.X.X
project.description=Demo project for info endpoint
info.build.artifact=@project.artifactId@
info.build.name=@project.name@
info.build.description=@project.description@
info.build.version=@project.version@

6

Basit bir çözüm kolaylığı için bu Kütüphaneyi kullanın. Manifest'e ihtiyacınız olan her şeyi ekleyin ve ardından dizeye göre sorgulayın.

 System.out.println("JAR was created by " + Manifests.read("Created-By"));

http://manifests.jcabi.com/index.html


3

Bazen Maven komut satırı, proje sürümüyle ilgili bir şey komut dosyası oluştururken, örneğin bir depodan URL yoluyla yapay nesne almak için yeterlidir:

mvn help:evaluate -Dexpression=project.version -q -DforceStdout

Kullanım örneği:

VERSION=$( mvn help:evaluate -Dexpression=project.version -q -DforceStdout )
ARTIFACT_ID=$( mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout )
GROUP_ID_URL=$( mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout | sed -e 's#\.#/#g' )
curl -f -S -O http://REPO-URL/mvn-repos/${GROUP_ID_URL}/${ARTIFACT_ID}/${VERSION}/${ARTIFACT_ID}-${VERSION}.jar

1
    <build>
            <finalName>${project.artifactId}-${project.version}</finalName>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-war-plugin</artifactId>
                        <version>3.2.2</version>
                        <configuration>
                            <failOnMissingWebXml>false</failOnMissingWebXml>
                            <archive>
                                <manifest>
                                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                                </manifest>
                            </archive>
                        </configuration>
                    </plugin>
                 </plugins>
            </pluginManagement>
</build>

Sürüm Kullanarak Alın this.getClass().getPackage().getImplementationVersion()

PS Eklemeyi unutmayın:

<manifest>
    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>

0

Atıfla ketankk cevabı :

Ne yazık ki, bunu ekleyerek uygulamamın kaynaklarla nasıl başa çıktığını ekledi:

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
    </resource>
  </resources>   
</build>

Ancak bunu maven-assemble-plugin'in <manifest> etiketi içinde kullanmak hile yaptı:

<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>

Bu yüzden kullanarak sürüm elde edebildim

String version = getClass().getPackage().getImplementationVersion();
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.