Есть ли способ читать содержимое файла jar. например, я хочу прочитать файл манифеста, чтобы найти создателя файла и версии jar. Есть ли способ достичь того же.
Чтение файла MANIFEST.MF из файла jar с использованием JAVA
Ответ 1
Следующий код должен помочь:
JarInputStream jarStream = new JarInputStream(stream);
Manifest mf = jarStream.getManifest();
Обработка исключений остается для вас:)
Ответ 2
Вы можете использовать что-то вроде этого:
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;
}
Чтобы получить атрибуты манифеста, вы можете перебирать переменную mainAttribs или напрямую извлекать требуемый атрибут, если знаете ключ.
Этот код проходит через каждую банку в пути к классам и читает MANIFEST каждого из них. Если вы знаете имя банки, вы можете посмотреть только URL-адрес, если он содержит() имя интересующей вас банку.
Ответ 3
Я предлагаю сделать следующее:
Package aPackage = MyClassName.class.getPackage();
String implementationVersion = aPackage.getImplementationVersion();
String implementationVendor = aPackage.getImplementationVendor();
Где MyClassName может быть любым классом из вашего приложения, написанного вами.
Ответ 4
Я реализовал класс AppVersion в соответствии с некоторыми идеями из stackoverflow, здесь я просто разделяю весь класс:
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;
}
}
В принципе, этот класс может считывать информацию о версии из манифеста своего собственного файла JAR или папки манифеста в нем. И, надеюсь, он работает на разных платформах, но я тестировал его только на Mac OS X.
Я надеюсь, что это было бы полезно для кого-то другого.
Ответ 5
Вы можете использовать служебный класс Manifests
из jcabi-manifestests:
final String value = Manifests.read("My-Version");
Класс найдет все MANIFEST.MF
файлы, доступные в пути к классам, и прочитает атрибут, который вы ищете, из одного из них. Также прочтите следующее: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
Ответ 6
Держите его простым. A JAR
также является ZIP
, поэтому любой код 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();
}
Несмотря на гибкость, для простого чтения данных этот лучший ответ.
Ответ 7
Получить атрибуты этим простым способом
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;
}