Java 读我自己的罐子';让我们看一下舱单
这是对一个请求的响应。因为这个答案很老(2009年),而且对我来说也不管用,所以我想问一下是否有人知道原因 我的用例是开发一个供内部使用的gradle插件。无论何时应用插件,我都非常希望能够打印出使用的插件版本。因此,我在构建插件时将版本写入插件的清单中,并在应用插件时尝试使用链接答案中的技术从清单中读取版本 我按照答案写了一些代码,但不起作用。我添加了一堆调试代码,我可以看到代码首先找到JDK本身提供的清单:Java 读我自己的罐子';让我们看一下舱单,java,eclipse,gradle,manifest.mf,Java,Eclipse,Gradle,Manifest.mf,这是对一个请求的响应。因为这个答案很老(2009年),而且对我来说也不管用,所以我想问一下是否有人知道原因 我的用例是开发一个供内部使用的gradle插件。无论何时应用插件,我都非常希望能够打印出使用的插件版本。因此,我在构建插件时将版本写入插件的清单中,并在应用插件时尝试使用链接答案中的技术从清单中读取版本 我按照答案写了一些代码,但不起作用。我添加了一堆调试代码,我可以看到代码首先找到JDK本身提供的清单: Manifest-Version: 1.0 Created-By: 1.7.0_07
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");
这是引发异常的行
有人能解释这种奇怪的行为,或者想出另一种,也许是新的方式来阅读清单吗
顺便说一下,这是在Eclipse下运行的,在Windows中。我还没有在Linux上尝试过它,在Linux上它可能真的可以工作,但我希望它在这两种情况下都能工作。如果是我,我会在构建时生成一个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()
我们可以利用Java类加载器在Java.lang.Package中已经提供的功能,而不是试图读取清单,以及奇怪的IO问题(,我仍然想理解它)。有一个
私有包(字符串名、Manifest man、URL、ClassLoader)
构造函数,当从jar加载包时会调用它。它读取清单的标准属性并将其存储在包成员变量中:
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;
这些清单条目必须具有适当的键,如“Implementation Version”等,可在java.util.jar.Attributes.Name
根据这些标准构建清单后,无需再次读取即可获得这些值。帽尖给谢谢。这对于我的特定用例很有用。我仍然想知道为什么FileNotFoundException在我原来的方法中发生。不知道,也许你没有关闭上一个inputstream?Tapestry IOC做了一些类似的事情,不是吗。我想到了这一点,并确保我确实关闭了前一个inputstream,这没有任何帮助。您计划阅读清单的哪些属性?很多与版本相关的清单属性都可以作为类的方法使用。是的,我刚刚发现了同样的东西,谢谢。请看我刚刚发布的答案。
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;