簡體   English   中英

Java 在運行時獲取 maven 依賴的版本

[英]Java get version of maven dependency at runtime

是否可以在運行時檢索特定 maven 依賴項的版本?

例如對於 pom.xml:

<dependency>
    <groupId>foo.bar</groupId>
    <artifactId>foobar</artifactId>
    <version>1.0</version>
</dependency>

我想使用工件 ID foobar檢索特定依賴項的1.0版本。

這里最有問題的部分是通過其名稱找到 JAR。 不幸的是,在 Java 中沒有 100% 可靠的方法。 要按名稱獲取 JAR,您需要掃描可能並不總是存在的正在運行的應用程序的類路徑(例如,因為使用自定義 class 加載器或使用模塊路徑而不是類路徑)。

但是讓我們假設您沒有使用任何花哨的功能,例如自定義 class 加載程序,並且您的類路徑包含所有 Maven 依賴項。 你現在需要做什么? 我將嘗試描述一個粗略的算法:

  • 從類路徑中檢索所有 JAR 文件的路徑。
  • 掃描每個 JAR 文件並找到文件pom.properties 它位於 META-INF/maven/{groupId}/{artifactId}。
  • pom.properties中查找version屬性的值。

同樣,這個解決方案也不是完全可靠的。 您必須決定:您是否真的需要版本信息以及用於什么目的?

您在看自己創建的 jars 嗎? 還是第三方庫? 我已經為前者發布了一個輕量級的解決方案。 因此,如果您在運行時正在尋找的 jars 的包裝掌握在自己手中,請先嘗試 go;-)。 它可能比必須讀取 XML 或 jar 文件中的屬性更優雅一些。

這個想法

  1. 使用Java 服務加載器方法能夠在以后添加盡可能多的組件/工件,它們可以在運行時貢獻自己的版本。 創建一個非常輕量級的庫,只需幾行代碼即可讀取、查找、過濾和排序類路徑上的所有工件版本。
  2. 創建一個maven 源代碼生成器插件,在編譯時為每個模塊生成服務實現,package 在每個 jars 中生成一個非常簡單的服務。

解決方案

解決方案的第一部分是artifact-version-service庫,現在可以在githubMavenCentral上找到它。 它涵蓋了服務定義和在運行時獲取工件版本的幾種方法。

第二部分是artifact-version-maven-plugin ,也可以在githubMavenCentral上找到。 它用於有一個輕松的生成器來實現每個工件的服務定義。

例子

獲取所有帶有坐標的模塊

不再閱讀 jar manifests,只是一個簡單的方法調用:

// iterate list of artifact dependencies
for (Artifact artifact : ArtifactVersionCollector.collectArtifacts()) {
    // print simple artifact string example
    System.out.println("artifact = " + artifact);
}

返回一組排序的工件。 要修改排序順序,請提供自定義比較器:

new ArtifactVersionCollector(Comparator.comparing(Artifact::getVersion)).collect();

這樣返回的工件列表按版本號排序。

查找特定的工件

ArtifactVersionCollector.findArtifact("foo.bar", "foobar");

獲取特定工件的版本詳細信息。

查找具有匹配 groupId(s) 的工件

查找所有具有 groupId foo.bar的工件(完全匹配):

ArtifactVersionCollector.findArtifactsByGroupId("foo.bar", true);

查找 groupIdfoo.bar開頭的所有工件:

ArtifactVersionCollector.findArtifactsByGroupId("foo.bar", false);

按版本號排序結果:

new ArtifactVersionCollector(Comparator.comparing(Artifact::getVersion)).artifactsByGroupId("foo.", false);

對工件列表實施自定義操作

通過提供 lambda,第一個示例可以這樣實現:

ArtifactVersionCollector.iterateArtifacts(a -> {
    System.out.println(a);
    return false;
});

安裝

將這兩個標簽添加到所有pom.xml文件中,或者添加到某處的公司主 pom 中:

<build>
  <plugins>
    <plugin>
      <groupId>de.westemeyer</groupId>
      <artifactId>artifact-version-maven-plugin</artifactId>
      <version>1.0.2</version>
      <executions>
        <execution>
          <goals>
            <goal>generate-service</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

<dependencies>
  <dependency>
    <groupId>de.westemeyer</groupId>
    <artifactId>artifact-version-service</artifactId>
    <version>1.0.2</version>
  </dependency>
</dependencies>

我剛剛發布了一個教程,其中包含一些方法來獲取您在項目中使用的所有工件的版本。 您也可以將其調整為單個依賴項。

pom.xml

<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>WDProject</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>WDProject</name>
    <url>http://www.nosite.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>

        <selenium.version>3.141.59</selenium.version>
        <webdrivermanager.version>3.7.1</webdrivermanager.version>

    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>${webdrivermanager.version}</version>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-api</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-server</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-remote-driver</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.lingala.zip4j</groupId>
            <artifactId>zip4j</artifactId>
            <version>2.2.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-model</artifactId>
            <version>3.3.9</version>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

盡管您想要搜索特定的依賴項,但下面的代碼會檢索 pom 文件中可用的依賴項的所有詳細信息。 您只需要創建一個包裝器方法來檢索特定依賴項的詳細信息。


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;


class SampleMavenDependencyReader {

    public static void main(String[] args) throws IOException, XmlPullParserException {
        MavenXpp3Reader reader = new MavenXpp3Reader();
        Model model = reader.read(new FileReader("/Users/nonadmin/bins/projects/IdeaProjects/WDProject/pom.xml"));

        for (int i = 0; i < model.getDependencies().size(); i++) {
            System.out.println(model.getDependencies().get(i));
        }
    }
}

OUTPUT

Dependency {groupId=junit, artifactId=junit, version=4.11, type=jar}
Dependency {groupId=io.github.bonigarcia, artifactId=webdrivermanager, version=${webdrivermanager.version}, type=jar}
Dependency {groupId=org.seleniumhq.selenium, artifactId=selenium-api, version=${selenium.version}, type=jar}
Dependency {groupId=org.seleniumhq.selenium, artifactId=selenium-server, version=${selenium.version}, type=jar}
Dependency {groupId=org.seleniumhq.selenium, artifactId=selenium-remote-driver, version=${selenium.version}, type=jar}
Dependency {groupId=org.seleniumhq.selenium, artifactId=selenium-java, version=${selenium.version}, type=jar}
Dependency {groupId=net.lingala.zip4j, artifactId=zip4j, version=2.2.4, type=jar}
Dependency {groupId=org.apache.maven, artifactId=maven-model, version=3.3.9, type=jar}~~~

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM