extension - leyendo el archivo MANIFEST.MF del archivo jar usando JAVA
manifest.mf main class (6)
¿Hay alguna manera de que pueda leer el contenido de un archivo jar? como quiero leer el archivo de manifiesto para encontrar el creador del archivo jar y la versión. ¿Hay alguna manera de lograr lo mismo.
El siguiente código debería ayudar:
JarInputStream jarStream = new JarInputStream(stream);
Manifest mf = jarStream.getManifest();
El manejo de excepciones queda para ti :)
Implementé una clase de AppVersion de acuerdo con algunas ideas de , aquí solo comparto toda la clase:
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;
}
}
Básicamente, esta clase puede leer la información de versión del manifiesto de su propio archivo JAR, o el manifiesto en su carpeta de clases. Y espero que funcione en diferentes plataformas, pero hasta ahora solo lo he probado en Mac OS X.
Espero que esto sea útil para otra persona.
Mantenlo simple. Un JAR
también es un ZIP
por lo que cualquier ZIP
se puede usar para leer el 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();
}
A pesar de la flexibilidad, solo para leer datos this respuesta es la mejor.
Podrías usar algo como esto:
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;
}
Para obtener los atributos de manifiesto, puede iterar sobre la variable "mainAttribs" o recuperar directamente el atributo requerido si conoce la clave.
Este código recorre cada jarra en el classpath y lee el MANIFEST de cada uno. Si conoce el nombre del frasco, es posible que solo desee consultar la URL si contiene () el nombre del frasco en el que está interesado.
Puede utilizar una clase de utilidad Manifests
de jcabi-manifests :
final String value = Manifests.read("My-Version");
La clase encontrará todos los archivos MANIFEST.MF
disponibles en classpath y leerá el atributo que está buscando en uno de ellos. También, lea esto: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
Sugeriría hacer lo siguiente:
Package aPackage = MyClassName.class.getPackage();
String implementationVersion = aPackage.getImplementationVersion();
String implementationVendor = aPackage.getImplementationVendor();
Donde MyClassName puede ser cualquier clase de su aplicación escrita por usted.