代码之家  ›  专栏  ›  技术社区  ›  Armand

运行时获取maven工件版本

  •  156
  • Armand  · 技术社区  · 15 年前

    我注意到在Maven工件的JAR中,project.version属性包含在两个文件中:

    META-INF/maven/${groupId}/${artifactId}/pom.properties
    META-INF/maven/${groupId}/${artifactId}/pom.xml
    

    在运行时是否有推荐的方法读取此版本?

    7 回复  |  直到 15 年前
        1
  •  237
  •   Anton Eliasson Joachim Sauer    11 年前

    您不需要访问Maven特定的文件来获取任何给定库/类的版本信息。

    你可以简单地使用 getClass().getPackage().getImplementationVersion() 获取存储在.jar文件中的版本信息 MANIFEST.MF 幸运的是,马文足够聪明 不幸的是,默认情况下,Maven没有将正确的信息写入清单!

    相反,我们必须修改 <archive> 的配置元素 maven-jar-plugin 设置 addDefaultImplementationEntries addDefaultSpecificationEntries true ,如下所示:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>                   
                <manifest>
                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                </manifest>
            </archive>
        </configuration>
    </plugin>
    

    理想情况下,这种配置应该放在公司中 pom 或者另一个基础POM。

    详细文件 <存档> 元素可以在 Maven Archive documentation

        2
  •  67
  •   thomas.mc.work    7 年前

    跟进以上答案 .war 工件,我发现我必须应用等价的配置 maven-war-plugin ,而不是 maven-jar-plugin :

    <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1</version>
        <configuration>
            <archive>                   
                <manifest>
                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                </manifest>
            </archive>
        </configuration>
    </plugin>
    

    这将版本信息添加到 MANIFEST.MF 在项目的 .jar (包括在 WEB-INF/lib 战争 )

        3
  •  25
  •   The Alchemist    11 年前

    下面是一个从pom.properties获取版本的方法,返回到从清单获取版本。

    public synchronized String getVersion() {
        String version = null;
    
        // try to load from maven properties first
        try {
            Properties p = new Properties();
            InputStream is = getClass().getResourceAsStream("/META-INF/maven/com.my.group/my-artefact/pom.properties");
            if (is != null) {
                p.load(is);
                version = p.getProperty("version", "");
            }
        } catch (Exception e) {
            // ignore
        }
    
        // fallback to using Java API
        if (version == null) {
            Package aPackage = getClass().getPackage();
            if (aPackage != null) {
                version = aPackage.getImplementationVersion();
                if (version == null) {
                    version = aPackage.getSpecificationVersion();
                }
            }
        }
    
        if (version == null) {
            // we could not compute the version so use a blank
            version = "";
        }
    
        return version;
    } 
    
        4
  •  3
  •   will    11 年前

    我花了些时间在这两个主要的方法上,但它们都不适合我。我正在使用NetBeans进行构建,可能会有更多的进展。我有一些来自Maven3的错误和警告,有些构造,但我认为这些很容易纠正。没什么大不了的。

    我确实找到了一个看起来可以维护且易于实现的答案,在这篇关于dzone的文章中:

    我已经有了一个resources/config子文件夹,并将我的文件命名为app.properties,以便更好地反映我们可能保留在那里的内容(如支持URL等)。

    唯一要注意的是,NetBeans发出了一个警告,即IDE需要过滤掉。不确定地点/方式。在这一点上没有效果。如果我需要跨过那座桥的话,也许还有工作要做。祝你好运。

        5
  •  2
  •   Community Mohan Dere    8 年前

    我正在使用 maven-assembly-plugin 为我的Maven包装。使用 Apache Maven Archiver 在里面 Joachim Sauer's answer 也可以工作:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <manifest>
                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                </manifest>
            </archive>
        </configuration>
        <executions>
            <execution .../>
        </executions>
    </plugin>
    

    因为阿奇华是 maven shared components ,它可以被多个maven构建插件使用,如果引入两个或多个插件,也可能会产生冲突,包括 archive 内部配置。

        6
  •  1
  •   Luke Hutchison    9 年前

    要在Eclipse和Maven构建中运行此程序,您应该添加 addDefaultImplementationEntries addDefaultSpecificationEntries 其他回复中描述的POM条目,然后使用以下代码:

    public synchronized static final String getVersion() {
        // Try to get version number from pom.xml (available in Eclipse)
        try {
            String className = getClass().getName();
            String classfileName = "/" + className.replace('.', '/') + ".class";
            URL classfileResource = getClass().getResource(classfileName);
            if (classfileResource != null) {
                Path absolutePackagePath = Paths.get(classfileResource.toURI())
                        .getParent();
                int packagePathSegments = className.length()
                        - className.replace(".", "").length();
                // Remove package segments from path, plus two more levels
                // for "target/classes", which is the standard location for
                // classes in Eclipse.
                Path path = absolutePackagePath;
                for (int i = 0, segmentsToRemove = packagePathSegments + 2;
                        i < segmentsToRemove; i++) {
                    path = path.getParent();
                }
                Path pom = path.resolve("pom.xml");
                try (InputStream is = Files.newInputStream(pom)) {
                    Document doc = DocumentBuilderFactory.newInstance()
                            .newDocumentBuilder().parse(is);
                    doc.getDocumentElement().normalize();
                    String version = (String) XPathFactory.newInstance()
                            .newXPath().compile("/project/version")
                            .evaluate(doc, XPathConstants.STRING);
                    if (version != null) {
                        version = version.trim();
                        if (!version.isEmpty()) {
                            return version;
                        }
                    }
                }
            }
        } catch (Exception e) {
            // Ignore
        }
    
        // Try to get version number from maven properties in jar's META-INF
        try (InputStream is = getClass()
            .getResourceAsStream("/META-INF/maven/" + MAVEN_PACKAGE + "/"
                    + MAVEN_ARTIFACT + "/pom.properties")) {
            if (is != null) {
                Properties p = new Properties();
                p.load(is);
                String version = p.getProperty("version", "").trim();
                if (!version.isEmpty()) {
                    return version;
                }
            }
        } catch (Exception e) {
            // Ignore
        }
    
        // Fallback to using Java API to get version from MANIFEST.MF
        String version = null;
        Package pkg = getClass().getPackage();
        if (pkg != null) {
            version = pkg.getImplementationVersion();
            if (version == null) {
                version = pkg.getSpecificationVersion();
            }
        }
        version = version == null ? "" : version.trim();
        return version.isEmpty() ? "unknown" : version;
    }
    

    如果Java构建将目标类放置在“目标/类”之外,那么您可能需要调整StuttSturMeFoT的值。

        7
  •  -1
  •   onderbewustzijn    7 年前

    用Maven项目在WAR文件中使用EJB的Java 8变体。在EAP 7.0上测试。

    @Log4j // lombok annotation
    @Startup
    @Singleton
    public class ApplicationLogic {
    
        public static final String DEVELOPMENT_APPLICATION_NAME = "application";
    
        public static final String DEVELOPMENT_GROUP_NAME = "com.group";
    
        private static final String POM_PROPERTIES_LOCATION = "/META-INF/maven/" + DEVELOPMENT_GROUP_NAME + "/" + DEVELOPMENT_APPLICATION_NAME + "/pom.properties";
    
        // In case no pom.properties file was generated or wrong location is configured, no pom.properties loading is done; otherwise VERSION will be assigned later
        public static String VERSION = "No pom.properties file present in folder " + POM_PROPERTIES_LOCATION;
    
        private static final String VERSION_ERROR = "Version could not be determinated";
    
        {    
            Optional.ofNullable(getClass().getResourceAsStream(POM_PROPERTIES_LOCATION)).ifPresent(p -> {
    
                Properties properties = new Properties();
    
                try {
    
                    properties.load(p);
    
                    VERSION = properties.getProperty("version", VERSION_ERROR);
    
                } catch (Exception e) {
    
                    VERSION = VERSION_ERROR;
    
                    log.fatal("Unexpected error occured during loading process of pom.properties file in META-INF folder!");
                }
            });
        }
    }