Java 在EAR中以编程方式从JAR读取Manifest.MF

Java 在EAR中以编程方式从JAR读取Manifest.MF,java,jar,Java,Jar,我必须扫描耳朵,通过阅读清单来确定其中一个罐子的版本 我碰巧读到了类似的内容:MyApplication.ear/MyLibrary.jar/META-INF/Manifest.MF 我想不出最简单的方法是什么。。。我一直在与JarFile、JarInputStream、JarURLConnection做斗争,但到目前为止运气不佳 以下是我当时的情况: JarFile myEAR = new JarFile(urlOfMyEAR); JarEntry myJAR = myEAR.getJarEn

我必须扫描耳朵,通过阅读清单来确定其中一个罐子的版本

我碰巧读到了类似的内容:MyApplication.ear/MyLibrary.jar/META-INF/Manifest.MF

我想不出最简单的方法是什么。。。我一直在与JarFile、JarInputStream、JarURLConnection做斗争,但到目前为止运气不佳

以下是我当时的情况:

JarFile myEAR = new JarFile(urlOfMyEAR);
JarEntry myJAR = myEAR.getJarEntry(libname);
Attributes m = myJAR.getAttributes();
System.out.println(m.getValue("Implementation-Version"));
但是
getAttributes()
返回
null

我想肯定有一种复杂的方法(通过提取文件或其他方式)来实现,但我希望有一种更简单的方法

谢谢你的帮助


编辑:下面是我自己的答案…

如果扫描器与应用程序在同一个JVM中运行,您可以获得如下清单文件:

Enumeration<URL> resources = this.getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
while(resources.hasMoreElements()){
    URL u = resources.nextElement();
    try(InputStream is = u.openStream()){
        if(is!=null){
            Manifest manifest = new Manifest(is);
            //do something blabla
        }
    }
}
Enumeration resources=this.getClass().getClassLoader().getResources(“META-INF/MANIFEST.MF”);
while(resources.hasMoreElements()){
URL u=resources.nextElement();
try(InputStream=u.openStream()){
如果(is!=null){
舱单=新舱单(is);
//胡说八道
}
}
}

如果没有,我认为在应用程序中添加一个简单的jar来收集这些数据,然后将结果上传到仪表板将是一个更好的解决方案。

我通过使用以下代码来解决我的问题:

JarFile myEAR = new JarFile(urlOfMyEAR);

File f = File.createTempFile("jar", null);
FileOutputStream resourceOS = new FileOutputStream(f);
byte[] byteArray = new byte[1024];
int i;

InputStream jarIS = myEAR.getInputStream(myEAR.getEntry(libname));
while ((i = jarIS.read(byteArray)) > 0) {
    //Write the bytes to the output stream
    resourceOS.write(byteArray, 0, i);
}
//Close streams to prevent errors
jarIS.close();
resourceOS.close();

JarFile myJAR = new JarFile(f);

Attributes m = myJAR.getManifest().getMainAttributes();

System.out.println(m.getValue("Implementation-Version"));
(感谢这篇文章)

在一个近200MB的耳朵里,一个7MB的罐子只需7秒钟就可以完成整个解压缩过程


谢谢你们的想法,伙计们。

罐子在你们的控制之下吗?你用Maven吗?您可以使用maven“过滤”将您的版本号注入到您需要的任何文件中…它实际上不在我的控制范围内,我希望在多个环境中读取应用程序的版本,并将其集成到仪表板中。。。指定的JAR是我们的框架,我需要向我的用户显示应用程序版本号以及它所基于的框架版本号……如果您使用的是Maven(或任何sofisticated构建工具),例如,您可以在构建时将您使用的各种版本号直接注入html模板中。。。因此,不需要读取jar,也不需要将范围限制在嵌入的依赖项上——例如,您可以注入(预期的)JDBC驱动程序版本号,这不应该在ear中提供。。如果没有Maven,您应该尝试定位jar,将其作为ZipFile打开,循环找到正确的条目,然后在内存中解压,最后解析清单。。。但这是一个棘手的spi,不幸的是,我改变现有流程的可能性很小(大公司中的大型应用程序),因此如果我想快速得到结果,我必须自己解决它(目前为止不是很devops^^)。最后,使用maven是一个可行的选择,我们已经考虑过了……遗憾的是,它不在同一个JVM上。。。“添加一个简单的jar…”我不太明白。正如你提到的@Pataluc,jar是你的框架。你可以在你的框架中添加扫描仪,在启动时运行并上传结果。我在一家大公司,我没有权限修改框架;(@ PATALUC如果你的项目中使用了Maven,你可以考虑开发一个Maven插件来通过扫描POM文件来获得结果,并且你可以将插件集成到CI工具中,而不用改变你的应用程序或框架。