코드의 maven pom.xml에서 버전 검색


255

프로그래밍 방식으로 코드에서 maven의 pom.xml에서 버전 번호를 검색하는 가장 간단한 방법은 무엇입니까?

답변:


262

Java를 사용한다고 가정하면

  1. 디렉토리 .properties에 (가장 일반적으로) 파일을 작성하십시오 src/main/resources(그러나 4 단계에서 다른 곳을 보도록 지시 할 수 있습니다).

  2. .properties프로젝트 버전의 표준 Maven 속성을 사용 하여 파일 의 일부 속성 값을 설정하십시오 . foo.bar=${project.version}

  3. Java 코드에서 특성 파일의 값을 클래스 경로의 자원으로로드하십시오 (Google은이를 수행하는 방법에 대한 예는 많지만 여기에는 starters에 대한 예가 있습니다 ).

  4. Maven에서 리소스 필터링을 활성화하면 Maven이 해당 파일을 출력 클래스로 복사하고 해당 복사본 동안 리소스를 변환하여 속성을 해석합니다. 당신은 여기에 몇 가지 정보를 찾을 수 있지만 당신은 대부분 당신의 치어 에서이 작업을 수행합니다 :

    <빌드>
      <자원>
        <자원>
          <directory> src / main / resources </ directory>
          <filtering> true </ filtering>
        </ resource>
      </ resources>   
    </ build>

당신은 또한 같은 다른 표준 속성을 얻을 수 있습니다 project.name, project.description당신이 당신의 치어에 넣어 또는 임의의 속성 <properties>, 메이븐 프로파일과 결합 등 자원 필터링, 당신에게 빌드시 변수 빌드 동작을 제공 할 수 있습니다. 로 런타임에 프로필을 지정하면 -PmyProfile빌드에 표시 될 수있는 속성을 활성화 할 수 있습니다.


2
나는 코드 발견 그 변화 메이븐 설정.
Wendel

7
src/main/resources이진 파일을 포함하여이 디렉토리에있는 모든 파일을 처리 할 수 ​​있으므로 에서 직접 필터링을 사용하지 마십시오 . 예측할 수없는 동작을 피하려면 여기에 제안 된대로src/main/resources-filtered 디렉토리에서 필터링을 수행하는 것이 좋습니다 . 어쨌든,이 멋진 트릭에 감사합니다!
SiZiOUS

1
실제 모델을 얻기 위해 MavenXppReader를 사용하는 아래의 대답은 값을 찾기 위해 아무것도 실행할 필요가 없으므로 실제로 유용합니다. 실행하기 전에 버전을 알아야하는 경우 아래 답변을보십시오. 체크 아웃 된 maven 프로젝트의 버전을 gradle에 알려주는 것이 매우 도움이되었으므로 미리 출력 jar 위치를 알 수있었습니다.
Ajax

92

허용되는 답변은 정적으로 응용 프로그램에 버전 번호를 가져 오는 가장 안정적이고 가장 좋은 방법 일 수 있지만 실제로 원래 질문에 대답하지는 않습니다. pom.xml에서 아티팩트의 버전 번호를 검색하는 방법은 무엇입니까? 따라서 런타임 중에 동적으로 수행하는 방법을 보여주는 대안을 제공하고 싶습니다 .

Maven 자체를 사용할 수 있습니다. 보다 정확하게는 Maven 라이브러리를 사용할 수 있습니다.

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

그런 다음 Java에서 다음과 같이하십시오.

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 업데이트 : Simon Sobisch의 후속 질문에 답변하기 위해 다음과 같이 예제를 수정했습니다.

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받는다는 - 조립 플러그인 포장 할 때 D 항아리 (종속 클래스가 통합되지 않은) 및 작동하지 않습니다 jar-with-dependenciesI GET a java.io.FileNotFoundException: pom.xml(마지막 항아리에 있음 META-INF/maven/my.package/myapp/pom.xml)-이것을 해결하는 방법에 대한 힌트가 있습니까?
Simon Sobisch

1
필자의 솔루션은 IDE 또는 콘솔에서 시작한 테스트 또는 도구에 사용될 때와 같이 개발 환경에서 동적으로 작동하도록 고안되었습니다. 이 질문에 대한 대답은 버전 번호를 아티팩트에 정적으로 패키지하는 몇 가지 방법을 보여줍니다. JAR에서 pom.xml을 사용할 수 있다고 가정하지 않았습니다. 그래도 거기에 있다는 것이 좋습니다. 파일 리더를 열 때 경로를 조정하여 클래스 로더 상황에 따라 달라질 수 있습니다. 나는 스스로 시도해야 할 것이다. 도움이되지 않는 경우 후속 질문을하십시오.
kriegaex

2
안녕하세요 @SimonSobisch, 나는 당신이 원하는 것을하는 방법을 보여주기 위해 대답을 업데이트했습니다. 그러나 방금 빠르고 더러운 것을 했으므로 중첩 생성자가있는 코드는 특히 마음에 들지 않습니다.
kriegaex

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

많은 응용 프로그램은이 파일을 사용하여 런타임에 응용 프로그램 / jar 버전을 읽습니다. 설정이 필요 없습니다.

위의 접근 방식의 유일한 문제는이 파일이 현재 package단계에서 생성 되어 테스트 중에 존재하지 않는다는 것입니다 (이를 변경하는 Jira 문제가 있습니다 ( MJAR-76 참조 )). 이것이 당신에게 문제가된다면, Alex가 설명한 접근법이 갈 길입니다.


10
속성을 읽는 예제를 찾는 사람들을 위해이 게시물은 여러 가지 방법을 설명합니다 -javablog.fr/…
chrismarx

43

Maven을 사용하여 앱 버전 번호를 표시하는 쉬운 방법에 설명 된 방법도 있습니다 .

이것을 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
이 솔루션은 저에게 효과적이지 않았습니다. 의 가치 getImplementationVersion()null입니다. (maven version 3.0.4)
Jesse Webb

7
단계에 따라 ... 아티팩트가 패키지 될 때만 작동하므로 단위 테스트에서는 작동하지 않습니다 :-/
wikier

2
들어 .war유물, 사용하는 것을 기억 maven-war-plugin대신maven-jar-plugin
cs_pupil

나에게 이것은 Tomcat 8 에서는 작동 하지만 Tomcat 7 에서는 작동하지 않습니다 ( getImplementationVersion()null 반환).
Alfonso Nishikawa

18

jar 또는 war와 같은 mvn 패키징을 사용하는 경우 다음을 사용하십시오.

getClass().getPackage().getImplementationVersion()

아카이브에서 생성 된 META-INF / MANIFEST.MF (pom.xml의 버전으로 설정)의 "Implementation-Version"속성을 읽습니다.


18

@kieste가 게시 한 내용을 보완하기 위해 Spring-boot를 사용하는 경우 Maven이 코드에서 사용할 수있는 정보를 빌드하는 가장 좋은 방법이라고 생각합니다 : http://docs.spring.io/spring-boot/ docs / current / reference / htmlsingle / # production-ready-application-info 는 매우 유용합니다.

당신은 단지 활성화 액츄에이터해야하고, 당신이 필요로하는 속성을 추가하여 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

프로젝트 버전과 관련된 것을 스크립팅 할 때 Maven 명령 행으로 충분할 수 있습니다 (예 : 리포지토리에서 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

ketankk의 답변 과 관련하여 :

불행히도 이것을 추가하면 내 응용 프로그램이 리소스를 처리하는 방식이 엉망이됩니다.

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

그러나 이것을 maven-assemble-plugin의 <manifest> 태그 내에서 사용하면 트릭을 수행했습니다.

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

그래서 나는 사용하여 버전을 얻을 수있었습니다.

String version = getClass().getPackage().getImplementationVersion();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.