कोड में maven pom.xml से संस्करण पुनः प्राप्त करें


255

कोड में मावेन के pom.xml से संस्करण संख्या को पुनः प्राप्त करने का सबसे सरल तरीका क्या है, अर्थात, प्रोग्रामेटिक रूप से?

जवाबों:


262

मान लें कि आप जावा का उपयोग कर रहे हैं, तो आप कर सकते हैं

  1. .propertiesअपनी src/main/resourcesनिर्देशिका में ( आमतौर पर) एक फ़ाइल बनाएं (लेकिन चरण 4 में आप इसे कहीं और देखने के लिए कह सकते हैं)।

  2. .propertiesपरियोजना संस्करण के लिए मानक मावेन संपत्ति का उपयोग करके अपनी फ़ाइल में कुछ संपत्ति का मूल्य निर्धारित करें : foo.bar=${project.version}

  3. अपने जावा कोड में, गुणों की फ़ाइल को classpath से संसाधन के रूप में लोड करें (यह कैसे करना है इसके प्रचुर उदाहरण के लिए Google, लेकिन यहां शुरुआत के लिए एक उदाहरण है )।

  4. मावेन में, संसाधन फ़िल्टरिंग सक्षम करें - इससे मावेन उस फ़ाइल को आपकी आउटपुट कक्षाओं में कॉपी कर देगा और उस कॉपी के दौरान संसाधन का अनुवाद कर सकता है, संपत्ति की व्याख्या करेगा। आप यहाँ कुछ जानकारी पा सकते हैं, लेकिन आप ज्यादातर अपने पोम में ऐसा करते हैं:

    <निर्माण>
      <संसाधनों>
        <संसाधन>
          <निर्देशिका> src / मुख्य / संसाधनों </ निर्देशिका>
          <छानने> सच </ छानने>
        </ संसाधन>
      </ संसाधनों>   
    </ निर्माण>

आप अन्य मानक गुणों को भी प्राप्त कर सकते हैं project.name, जैसे project.descriptionकि, या यहां तक ​​कि मनमानी गुण जो आप अपने पोम में डालते हैं <properties>, आदि। संसाधन फ़िल्टरिंग, मावेन प्रोफाइल के साथ मिलकर, आप बिल्ड समय पर परिवर्तनशील निर्माण व्यवहार दे सकते हैं। जब आप रनटाइम के साथ एक प्रोफ़ाइल निर्दिष्ट करते हैं -PmyProfile, तो यह उन गुणों को सक्षम कर सकता है जो आपके निर्माण में दिखाई दे सकते हैं।


2
मैं एक कोड पाया इस कि कोई परिवर्तन नहीं Maven config।
वेंडेल

7
सीधे फ़िल्टरिंग का उपयोग करने से सावधान रहें src/main/resources, क्योंकि यह इस निर्देशिका में स्थित सभी फ़ाइलों को संसाधित कर सकता है, जिसमें बायनेरी फाइलें भी शामिल हैं। अप्रत्याशित व्यवहार से बचने के लिए, एक src/main/resources-filteredनिर्देशिका पर फ़िल्टरिंग करना बेहतर है , जैसा कि यहां सुझाया गया है । वैसे भी, इस अच्छी चाल के लिए धन्यवाद!
सियोजूस

1
वास्तविक मॉडल प्राप्त करने के लिए MavenXppReader का उपयोग करने के लिए नीचे दिया गया उत्तर वास्तव में उपयोगी है, क्योंकि इसे मूल्य खोजने के लिए कुछ भी चलाने की आवश्यकता नहीं है। उन मामलों में जहां आपको कुछ भी चलाने से पहले संस्करण को जानना होगा, नीचे दिए गए उत्तरों को देखें; यह मेरे लिए बहुत उपयोगी था कि मैं यह पता कर सकूं कि मावेन प्रोजेक्ट का चेक आउट संस्करण क्या है, इसलिए मुझे आउटपुट जार लोकेशन का पता चल सकता है।
अजाक्स

92

स्वीकृत उत्तर किसी एप्लिकेशन में संस्करण संख्या को सांख्यिकीय रूप से प्राप्त करने के लिए सबसे अच्छा और सबसे स्थिर तरीका हो सकता है , लेकिन वास्तव में मूल प्रश्न का उत्तर नहीं देता है: pom.xml से विरूपण साक्ष्य के संस्करण संख्या को कैसे पुनः प्राप्त करें? इस प्रकार, मैं एक विकल्प दिखाना चाहता हूं कि यह रनटाइम के दौरान गतिशील रूप से कैसे किया जाए :

आप मावेन का उपयोग कर सकते हैं। अधिक सटीक होने के लिए, आप मावेन लाइब्रेरी का उपयोग कर सकते हैं।

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

और फिर जावा में ऐसा कुछ करें:

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());
    }
}

कंसोल लॉग निम्नानुसार है:

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

अपडेट 2017-10-31: साइमन सोबिश के अनुवर्ती प्रश्न का उत्तर देने के लिए मैंने इस तरह के उदाहरण को संशोधित किया:

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
यह लगभग उसी के समान है जो मैं ग्रहण से शुरू होने पर उपयोग करता हूं और ठीक काम करता हूं, लेकिन जब सामान्य packageडी जार से शुरू नहीं होता है (निर्भरता कक्षाएं एकीकृत नहीं होती हैं) और मावेन-असेंबली-प्लगइन के साथ पैक किए जाने पर काम नहीं करता है जो jar-with-dependenciesमुझे मिलता है। a java.io.FileNotFoundException: pom.xml(यह अंतिम जार में है के रूप में META-INF/maven/my.package/myapp/pom.xml) - किसी भी संकेत इसे हल करने के लिए कैसे?
साइमन सोबिस्क

1
मेरा समाधान विकास के वातावरण में गतिशील रूप से काम करने के लिए है, उदाहरण के लिए जब आईडीई या कंसोल से शुरू किए गए परीक्षणों या उपकरणों में उपयोग किया जाता है। इस प्रश्न का स्वीकृत उत्तर संस्करण संख्याओं को आपकी कलाकृतियों में वैधानिक रूप से पैकेज करने के कई तरीके दिखाता है। मैं यह नहीं मान रहा था कि pom.xml JARs के भीतर बिल्कुल उपलब्ध होगा। तुम्हारे लिए अच्छा है कि तुम वहाँ है, यद्यपि। हो सकता है कि आप फ़ाइल रीडर खोलते समय केवल पथ को समायोजित कर सकते हैं और हो सकता है कि यह क्लासलोडर की स्थिति पर निर्भर हो। मुझे अपने लिए प्रयास करना होगा। यदि यह मदद नहीं करता है तो अनुवर्ती प्रश्न पूछने के लिए स्वतंत्र महसूस करें।
क्रायजेक्स

2
हाय @SimonSobisch, मैंने अभी-अभी अपना उत्तर अपडेट किया है ताकि आप यह बता सकें कि आपको क्या करना है। लेकिन कृपया इस तथ्य से अवगत रहें कि मैंने इसे त्वरित और गंदा किया था, मुझे विशेष रूप से नेस्टेड कंस्ट्रक्टर वाले कोड पसंद नहीं हैं।
क्रायजेक्स ३१'१

75

पैकेज्ड कलाकृतियों में एक META-INF/maven/${groupId}/${artifactId}/pom.propertiesफाइल होती है जो सामग्री की तरह दिखाई देती है:

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

कई एप्लिकेशन रनटाइम पर एप्लिकेशन / जार संस्करण को पढ़ने के लिए इस फाइल का उपयोग करते हैं, इसके लिए शून्य सेटअप की आवश्यकता होती है।

उपरोक्त दृष्टिकोण के साथ एकमात्र समस्या यह है कि यह फ़ाइल (वर्तमान में) packageचरण के दौरान उत्पन्न होती है और इस प्रकार परीक्षण के दौरान मौजूद नहीं होगी, आदि (इसे बदलने के लिए एक जीरा मुद्दा है, MJAR-76 देखें )। यदि यह आपके लिए एक मुद्दा है, तो एलेक्स द्वारा वर्णित दृष्टिकोण जाने का रास्ता है।


10
- एक उदाहरण गुण पढ़ने के लिए देख रहे लोगों के लिए, इस पोस्ट के लिए कई तरीके के ऊपर जाता है javablog.fr/...
chrismarx

43

मावेन का उपयोग करके अपने एप्लिकेशन संस्करण संख्या को प्रदर्शित करने के लिए आसान तरीके से वर्णित विधि भी है :

इसे pom.xml में जोड़ें

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

तो इस का उपयोग करें:

App.class.getPackage().getImplementationVersion()

मुझे यह विधि सरल लग रही है।


18
-1 - यह समाधान मेरे काम नहीं आया; का मान getImplementationVersion()था null। (मावेन संस्करण 3.0.4)
जेसी वेब

7
चरण के आधार पर ... केवल तब काम करता है जब विरूपण साक्ष्य पैक किया जा रहा है, इसलिए यूनिट परीक्षणों पर काम नहीं करता है: - /
विकियर

2
के लिए .warकलाकृतियों, उपयोग करने के लिए याद maven-war-pluginकरने के बजायmaven-jar-plugin
cs_pupil

मेरे लिए, यह टॉमकैट 8 में काम करता है , लेकिन टॉमकैट 7 ( getImplementationVersion()रिटर्न शून्य) में काम नहीं करता है ।
अल्फांसो निशिकावा

18

यदि आप जार या युद्ध जैसे mvan पैकेजिंग का उपयोग करते हैं, तो उपयोग करें:

getClass().getPackage().getImplementationVersion()

यह संग्रह में उत्पन्न META-INF / MANIFEST.MF (जो pom.xml के संस्करण पर सेट है) का एक गुण "कार्यान्वयन-संस्करण" पढ़ता है।


18

@Kieste ने जो पोस्ट किया है, उसे पूरक करने के लिए, जो मुझे लगता है कि आपके कोड में Maven बिल्ड informations उपलब्ध होने का सबसे अच्छा तरीका है यदि आप स्प्रिंग-बूट का उपयोग कर रहे हैं: http://docs.spring.io/spring-boot/ पर प्रलेखन डॉक्स / वर्तमान / संदर्भ / htmlsingle / # उत्पादन-तैयार-अनुप्रयोग-जानकारी बहुत उपयोगी है।

आपको बस एक्ट्यूएटर्स को सक्रिय करने, और उन गुणों को जोड़ने की ज़रूरत है जो आपको अपनी ज़रूरत है application.propertiesयाapplication.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

एक सरल समाधान की आसानी के लिए इस लाइब्रेरी का उपयोग करें। आपको जो भी जरूरत है, उसे प्रकट करें और फिर स्ट्रिंग द्वारा क्वेरी करें।

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

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


3

कभी-कभी मावेन कमांड लाइन पर्याप्त होती है, जब परियोजना संस्करण से संबंधित किसी चीज़ की स्क्रिप्टिंग की जाती है, उदाहरण के लिए रिपॉजिटर्स द्वारा URL से आर्टवर्क पुनर्प्राप्ति के लिए:

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

उपयोग उदाहरण:

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>

संस्करण का उपयोग करें this.getClass().getPackage().getImplementationVersion()

पुनश्च जोड़ना न भूलें:

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

0

केटंक के उत्तर के संदर्भ में :

दुर्भाग्य से, यह जोड़ने के साथ कि मेरा आवेदन संसाधनों से कैसे निपटता है:

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

लेकिन इसके अंदर मावेन-असेंबल-प्लगइन के <मैनिफ़ेस्ट> टैग का उपयोग करके इस ट्रिक को किया:

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

इसलिए मैं संस्करण का उपयोग कर पाने में सक्षम था

String version = getClass().getPackage().getImplementationVersion();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.