读我自己的罐子的清单拿2

时间:2016-05-18 20:49:45

标签: java eclipse gradle manifest.mf

这是对near-universally accepted answerold question的回应。由于答案相当陈旧(2009年),因为它不适合我,我想我会问是否有人知道为什么。

我的用例是开发一个内部使用的gradle插件。每当插件应用时,我都非常希望能够打印正在使用的插件版本。因此,我在构建插件时将该版本写入插件的清单中,并尝试在应用插件时从清单中读取它,使用链接答案中的技术。

我根据答案编写了一些代码,但它没有用。我添加了一堆调试代码,我可以看到代码首先找到了JDK本身提供的Manifest:

Manifest-Version: 1.0
Created-By: 1.7.0_07 (Oracle Corporation)

然后它找到我的清单,我正在寻找的那个,但抛出一个FileNotFoundException:

java.io.FileNotFoundException:JAR条目META-INF / MANIFEST.MF找不到{我的本地maven存储库中的插件jar的路径}。怎么可能

        Enumeration<URL> resources = getClass().getClassLoader()
                .getResources("META-INF/MANIFEST.MF");

找到清单,然后在尝试使用以下内容时抛出FileNotFoundException:

Manifest manifest = new Manifest(resources.nextElement().openStream());

这是抛出异常的行。

有人可以解释这种奇怪的行为,或者想出另一种可能更新的阅读清单的方法吗?

顺便说一句,这是在Windows下运行的。还没有在Linux上尝试它,它可能实际工作,但我希望它在两种情况下都能工作。

2 个答案:

答案 0 :(得分:2)

如果是我,我会在构建时生成一个包含版本的java文件:

例如:将以下文件放在src/template/java/com/foo/MyPluginProperties.java

package com.foo;
public class MyPluginProperties {
   public static String getVersion() {
      return "@version@";
   }
}

然后在build.gradle

def generatedJava = file("$buildDir/generated/java")
task generateSource(type:Copy) {
    def tokens = [version: project.version]

    // configure task inputs for gradle's up-to-date checks
    inputs.property "tokens", tokens
    from "src/template/java"
    filter(ReplaceTokens, tokens: tokens)
    into generatedJava
}

// wire the task into the gradle DAG
compileJava.dependsOn generateSource

// add the generated directory to the main source set so it's compiled
sourceSets.main.java {
   srcDir generatedJava
}

然后,在您的插件中,您可以调用以下内容:

com.foo.MyPluginProperties.getVersion()

答案 1 :(得分:1)

我们可以利用Java类加载器在java.lang中已经提供的功能,而不是尝试读取清单,以及奇怪的IO问题(我仍然想要理解)。 。包。从jar加载包时会调用private Package(String name, Manifest man, URL url, ClassLoader loader)构造函数。它读取Manifest的标准属性并将它们存储在Package成员变量中:

private final String pkgName;
private final String specTitle;
private final String specVersion;
private final String specVendor;
private final String implTitle;
private final String implVersion;
private final String implVendor;

这些清单条目必须具有正确的密钥,例如“实施版本”等,可在java.util.jar.Attributes.Name

中找到

根据这些标准构建清单,可以在不执行其他读取的情况下获取这些值 。帽子提示到https://stackoverflow.com/a/23280647/811299