使用 JAVA 从 jar 文件中读取 MANIFEST.MF 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3777055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
reading MANIFEST.MF file from jar file using JAVA
提问by M.J.
Is there any way i can read the contents of a jar file. like i want to read the manifest file in order to find the creator of the jar file and version. Is there any way to achieve the same.
有什么办法可以读取jar文件的内容。就像我想阅读清单文件以找到 jar 文件和版本的创建者一样。有什么方法可以实现相同的目标。
采纳答案by oiavorskyi
Next code should help:
下一个代码应该有帮助:
JarInputStream jarStream = new JarInputStream(stream);
Manifest mf = jarStream.getManifest();
Exception handling is left for you :)
异常处理留给你:)
回答by flash
You could use something like this:
你可以使用这样的东西:
public static String getManifestInfo() {
Enumeration resEnum;
try {
resEnum = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
while (resEnum.hasMoreElements()) {
try {
URL url = (URL)resEnum.nextElement();
InputStream is = url.openStream();
if (is != null) {
Manifest manifest = new Manifest(is);
Attributes mainAttribs = manifest.getMainAttributes();
String version = mainAttribs.getValue("Implementation-Version");
if(version != null) {
return version;
}
}
}
catch (Exception e) {
// Silently ignore wrong manifests on classpath?
}
}
} catch (IOException e1) {
// Silently ignore wrong manifests on classpath?
}
return null;
}
To get the manifest attributes, you could iterate over the variable "mainAttribs" or directly retrieve your required attribute if you know the key.
要获取清单属性,您可以遍历变量“mainAttribs”或直接检索所需的属性(如果您知道密钥)。
This code loops through every jar on the classpath and reads the MANIFEST of each. If you know the name of the jar you may want to only look at the URL if it contains() the name of the jar you are interested in.
此代码循环遍历类路径上的每个 jar 并读取每个 jar 的 MANIFEST。如果您知道 jar 的名称,您可能只想查看包含 () 您感兴趣的 jar 名称的 URL。
回答by yegor256
You can use a utility class Manifests
from jcabi-manifests:
final String value = Manifests.read("My-Version");
The class will find all MANIFEST.MF
files available in classpath and read the attribute you're looking for from one of them. Also, read this: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
该类将查找MANIFEST.MF
类路径中可用的所有文件,并从其中一个文件中读取您要查找的属性。另外,请阅读:http: //www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
回答by Jake W
I implemented an AppVersion class according to some ideas from stackoverflow, here I just share the entire class:
我根据stackoverflow的一些想法实现了一个AppVersion类,这里我只分享整个类:
import java.io.File;
import java.net.URL;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AppVersion {
private static final Logger log = LoggerFactory.getLogger(AppVersion.class);
private static String version;
public static String get() {
if (StringUtils.isBlank(version)) {
Class<?> clazz = AppVersion.class;
String className = clazz.getSimpleName() + ".class";
String classPath = clazz.getResource(className).toString();
if (!classPath.startsWith("jar")) {
// Class not from JAR
String relativePath = clazz.getName().replace('.', File.separatorChar) + ".class";
String classFolder = classPath.substring(0, classPath.length() - relativePath.length() - 1);
String manifestPath = classFolder + "/META-INF/MANIFEST.MF";
log.debug("manifestPath={}", manifestPath);
version = readVersionFrom(manifestPath);
} else {
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF";
log.debug("manifestPath={}", manifestPath);
version = readVersionFrom(manifestPath);
}
}
return version;
}
private static String readVersionFrom(String manifestPath) {
Manifest manifest = null;
try {
manifest = new Manifest(new URL(manifestPath).openStream());
Attributes attrs = manifest.getMainAttributes();
String implementationVersion = attrs.getValue("Implementation-Version");
implementationVersion = StringUtils.replace(implementationVersion, "-SNAPSHOT", "");
log.debug("Read Implementation-Version: {}", implementationVersion);
String implementationBuild = attrs.getValue("Implementation-Build");
log.debug("Read Implementation-Build: {}", implementationBuild);
String version = implementationVersion;
if (StringUtils.isNotBlank(implementationBuild)) {
version = StringUtils.join(new String[] { implementationVersion, implementationBuild }, '.');
}
return version;
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return StringUtils.EMPTY;
}
}
Basically, this class can read version information from the manifest of its own JAR file, or the manifest in it's classes folder. And hopefully it works on different platforms, but I only tested it on Mac OS X so far.
基本上,这个类可以从它自己的 JAR 文件的清单或它的 classes 文件夹中的清单中读取版本信息。希望它能在不同的平台上工作,但到目前为止我只在 Mac OS X 上测试过它。
I hope this would be useful for someone else.
我希望这对其他人有用。
回答by stviper
I would suggest to make following:
我建议做以下事情:
Package aPackage = MyClassName.class.getPackage();
String implementationVersion = aPackage.getImplementationVersion();
String implementationVendor = aPackage.getImplementationVendor();
Where MyClassName can be any class from your application written by you.
其中 MyClassName 可以是您编写的应用程序中的任何类。
回答by BullyWiiPlaza
Keep it simple. A JAR
is also a ZIP
so any ZIP
code can be used to read the MAINFEST.MF
:
把事情简单化。AJAR
也是 aZIP
所以任何ZIP
代码都可以用来读取MAINFEST.MF
:
public static String readManifest(String sourceJARFile) throws IOException
{
ZipFile zipFile = new ZipFile(sourceJARFile);
Enumeration entries = zipFile.entries();
while (entries.hasMoreElements())
{
ZipEntry zipEntry = (ZipEntry) entries.nextElement();
if (zipEntry.getName().equals("META-INF/MANIFEST.MF"))
{
return toString(zipFile.getInputStream(zipEntry));
}
}
throw new IllegalStateException("Manifest not found");
}
private static String toString(InputStream inputStream) throws IOException
{
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)))
{
String line;
while ((line = bufferedReader.readLine()) != null)
{
stringBuilder.append(line);
stringBuilder.append(System.lineSeparator());
}
}
return stringBuilder.toString().trim() + System.lineSeparator();
}
Despite the flexibility, for just reading data thisanswer is the best.
尽管具有灵活性,但对于仅读取数据而言,此答案是最好的。
回答by Ronald
Achieve the attributes in this simple way
以这种简单的方式获得属性
public static String getMainClasFromJarFile(String jarFilePath) throws Exception{
// Path example: "C:\Users\GIGABYTE\.m2\repository\domolin\DeviceTest\1.0-SNAPSHOT\DeviceTest-1.0-SNAPSHOT.jar";
JarInputStream jarStream = new JarInputStream(new FileInputStream(jarFilePath));
Manifest mf = jarStream.getManifest();
Attributes attributes = mf.getMainAttributes();
// Manifest-Version: 1.0
// Built-By: GIGABYTE
// Created-By: Apache Maven 3.0.5
// Build-Jdk: 1.8.0_144
// Main-Class: domolin.devicetest.DeviceTest
String mainClass = attributes.getValue("Main-Class");
//String mainClass = attributes.getValue("Created-By");
// Output: domolin.devicetest.DeviceTest
return mainClass;
}