阅读 class 的 jar 版本
Read the jar version for a class
对于网络服务客户端,我想使用 jar 文件中的 Implementation-Title 和 Implementation-Version 作为用户代理字符串。问题是如何读取 jar 的清单。
这个问题已经被问过很多次了,但是答案似乎不适合我。 (例如 Reading my own Jar's Manifest)
问题是简单地阅读 /META-INF/MANIFEST.MF 几乎总是给出错误的结果。在我的例子中,它几乎总是指 JBoss.
中提出的解决方案
对我来说是有问题的,因为你必须硬编码库名称来停止迭代,然后它仍然可能意味着同一个库的两个版本在 class 路径上而你只是 return 第一个- 不一定是对的 - 命中。
中的解决方案
似乎只能与 jar:// urls 一起使用,它在 JBoss 中完全失败,其中应用程序 classloader 生成 vfs:// urls.
有没有办法让 class 中的代码找到它自己的清单?
我从 java 命令行尝试了上述项目,这些项目在小型应用程序 运行 中似乎 运行 很好,但是我想有一个便携式解决方案,因为我不能预测我的图书馆以后会在哪里使用。
public static Manifest getManifest() {
log.debug("getManifest()");
synchronized(Version.class) {
if(manifest==null) {
try {
// this works wrongly in JBoss
//ClassLoader cl = Version.class.getProtectionDomain().getClassLoader();
//log.debug("found classloader={}", cl);
//URL manifesturl = cl.getResource("/META-INF/MANIFEST.MF");
URL jar = Version.class.getProtectionDomain().getCodeSource().getLocation();
log.debug("Class loaded from {}", jar);
URL manifesturl = null;
switch(jar.getProtocol()) {
case "file":
manifesturl = new URL(jar.toString()+"META-INF/MANIFEST.MF");
break;
default:
manifesturl = new URL(jar.toString()+"!/META-INF/MANIFEST.MF");
}
log.debug("Expecting manifest at {}", manifesturl);
manifest = new Manifest(manifesturl.openStream());
}
catch(Exception e) {
log.info("Could not read version", e);
}
}
}
代码将检测到正确的 jar 路径。我假设通过修改 url 指向清单会给出所需的结果但是我得到了这个:
Class loaded from vfs:/C:/Users/user/Documents/JavaLibs/wildfly-18.0.0.Final/bin/content/webapp.war/WEB-INF/lib/library-1.0-18.jar
Expecting manifest at vfs:/C:/Users/user/Documents/JavaLibs/wildfly-18.0.0.Final/bin/content/webapp.war/WEB-INF/lib/library-1.0-18.jar!/META-INF/MANIFEST.MF
Could not read version: java.io.FileNotFoundException: C:\Users\hiran\Documents\JavaLibs\wildfly-18.0.0.Final\standalone\tmp\vfs\temp\tempfc75b13f07296e98\content-e4d5ca96cbe6b35e\WEB-INF\lib\library-1.0-18.jar!\META-INF\MANIFEST.MF (The system cannot find the path specified)
我检查了那个路径,似乎甚至第一个 URL 到 jar(通过 Version.class.getProtectionDomain().getCodeSource().getLocation() 获得)已经是错误的。应该是C:\Users\user\Documents\JavaLibs\wildfly-18.0.0.Final\standalone\tmp\vfs\temp\tempfc75b13f07296e98\content-e4d5ca96cbe6b35e\WEB-INF\lib\library-1.0.18.jar.
所以这甚至可能指向 Wildfly 中的问题?
看来我在这里找到了一些合适的解决方案:
所以最终这段代码可以在 JBoss 中显示正确版本的 jar(至少):
this.getClass().getPackage().getImplementationTitle();
this.getClass().getPackage().getImplementationVersion();
希望下次搜索时能找到这个答案...
对于网络服务客户端,我想使用 jar 文件中的 Implementation-Title 和 Implementation-Version 作为用户代理字符串。问题是如何读取 jar 的清单。
这个问题已经被问过很多次了,但是答案似乎不适合我。 (例如 Reading my own Jar's Manifest)
问题是简单地阅读 /META-INF/MANIFEST.MF 几乎总是给出错误的结果。在我的例子中,它几乎总是指 JBoss.
中提出的解决方案 对我来说是有问题的,因为你必须硬编码库名称来停止迭代,然后它仍然可能意味着同一个库的两个版本在 class 路径上而你只是 return 第一个- 不一定是对的 - 命中。
中的解决方案 似乎只能与 jar:// urls 一起使用,它在 JBoss 中完全失败,其中应用程序 classloader 生成 vfs:// urls.
有没有办法让 class 中的代码找到它自己的清单?
我从 java 命令行尝试了上述项目,这些项目在小型应用程序 运行 中似乎 运行 很好,但是我想有一个便携式解决方案,因为我不能预测我的图书馆以后会在哪里使用。
public static Manifest getManifest() {
log.debug("getManifest()");
synchronized(Version.class) {
if(manifest==null) {
try {
// this works wrongly in JBoss
//ClassLoader cl = Version.class.getProtectionDomain().getClassLoader();
//log.debug("found classloader={}", cl);
//URL manifesturl = cl.getResource("/META-INF/MANIFEST.MF");
URL jar = Version.class.getProtectionDomain().getCodeSource().getLocation();
log.debug("Class loaded from {}", jar);
URL manifesturl = null;
switch(jar.getProtocol()) {
case "file":
manifesturl = new URL(jar.toString()+"META-INF/MANIFEST.MF");
break;
default:
manifesturl = new URL(jar.toString()+"!/META-INF/MANIFEST.MF");
}
log.debug("Expecting manifest at {}", manifesturl);
manifest = new Manifest(manifesturl.openStream());
}
catch(Exception e) {
log.info("Could not read version", e);
}
}
}
代码将检测到正确的 jar 路径。我假设通过修改 url 指向清单会给出所需的结果但是我得到了这个:
Class loaded from vfs:/C:/Users/user/Documents/JavaLibs/wildfly-18.0.0.Final/bin/content/webapp.war/WEB-INF/lib/library-1.0-18.jar
Expecting manifest at vfs:/C:/Users/user/Documents/JavaLibs/wildfly-18.0.0.Final/bin/content/webapp.war/WEB-INF/lib/library-1.0-18.jar!/META-INF/MANIFEST.MF
Could not read version: java.io.FileNotFoundException: C:\Users\hiran\Documents\JavaLibs\wildfly-18.0.0.Final\standalone\tmp\vfs\temp\tempfc75b13f07296e98\content-e4d5ca96cbe6b35e\WEB-INF\lib\library-1.0-18.jar!\META-INF\MANIFEST.MF (The system cannot find the path specified)
我检查了那个路径,似乎甚至第一个 URL 到 jar(通过 Version.class.getProtectionDomain().getCodeSource().getLocation() 获得)已经是错误的。应该是C:\Users\user\Documents\JavaLibs\wildfly-18.0.0.Final\standalone\tmp\vfs\temp\tempfc75b13f07296e98\content-e4d5ca96cbe6b35e\WEB-INF\lib\library-1.0.18.jar.
所以这甚至可能指向 Wildfly 中的问题?
看来我在这里找到了一些合适的解决方案:
所以最终这段代码可以在 JBoss 中显示正确版本的 jar(至少):
this.getClass().getPackage().getImplementationTitle();
this.getClass().getPackage().getImplementationVersion();
希望下次搜索时能找到这个答案...