Esiste un modo per leggere il contenuto di un file jar. come voglio leggere il file manifest per trovare il creatore del file jar e della versione. C'è un modo per ottenere lo stesso.lettura del file MANIFEST.MF dal file jar utilizzando JAVA
risposta
codice seguente dovrebbe aiutare:. Maneggevolezza
JarInputStream jarStream = new JarInputStream(stream);
Manifest mf = jarStream.getManifest();
Eccezione è a sinistra per voi :)
Si potrebbe usare qualcosa di simile:
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;
}
Per ottenere gli attributi si manifestano, si potrebbe iterare la variabile "mainAttribs" o direttamente recuperare l'attributo richiesto se si conosce la chiave.
Questo codice scorre in ogni jar del classpath e legge il MANIFEST di ciascuno. Se si conosce il nome del vaso si consiglia di guardare solo l'URL se contiene() il nome del vaso che ti interessa
È possibile utilizzare una classe di utilità Manifests
da jcabi-manifests:
final String value = Manifests.read("My-Version");
La classe troverà tutti MANIFEST.MF
file disponibili in classpath e leggi l'attributo che stai cercando da uno di essi. Inoltre, leggere questo: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
Questo è ottimo e funziona bene. Bello che è una biblioteca. Ciò che farebbe meglio se tutti i Manifesti venissero letti. Ho notato che Javadoc ha un 'entry()', che potrebbe essere quello che ho suggerito, tuttavia quel metodo non appare nella versione che sto usando (1.1 - l'ultima a questa data su MvnRepository). La risposta http://stackoverflow.com/a/3777116/1019307 ha la soluzione che ha funzionato per recuperare tutti i Manifests. – HankCa
ho implementato una classe appVersion secondo alcune idee da StackOverflow, qui ho solo condivido l'intera classe:
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;
}
}
In sostanza, questa classe in grado di leggere le informazioni sulla versione dal manifesto della sua proprio file JAR o manifest nella propria cartella delle classi. E speriamo che funzioni su piattaforme diverse, ma l'ho testato su Mac OS X finora.
Spero che questo possa essere utile per qualcun altro.
L'unico problema con questa è la riga contenente: String manifestPath = StringUtils.join [...] L'uso di File.separatorChar sembra generare un URL non valido in Windows ... probabilmente meglio usare "/". –
Grazie per aver segnalato questo. Avrà una prova e la modificherà. –
Waw, funziona.Grazie! –
vorrei suggerire di fare seguente:
Package aPackage = MyClassName.class.getPackage();
String implementationVersion = aPackage.getImplementationVersion();
String implementationVendor = aPackage.getImplementationVendor();
Dove MyClassName può essere qualsiasi classe dall'applicazione scritto da te.
Questa è la cosa di cui ho bisogno (per leggere 'Implementation-Version'). Purtroppo, questo non ha funzionato per me sulle classi decompresse, sebbene il manifest sia in "META-INF/MANIFEST.MF". –
Questo non funziona per impostazione predefinita a meno che non si aggiunga addDefaultImplementationEntries su true per maven-jar-plugin in modo che contenga effettivamente le informazioni sulla versione. Di default il file manifest non include nulla. Anche @Victor, prova ad eseguire il pacchetto mvn e vedere l'interno se ha informazioni corrette. Generalmente la configurazione di questa versione è in maven-jar-plugin o maven-war-plugin, quindi le classi non compresse non ce l'hanno. – wonhee
Semplicità. Un JAR
è anche un ZIP
in modo che qualsiasi codice ZIP
può essere utilizzato per leggere il 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();
}
Nonostante la flessibilità, solo per la lettura dei dati this risposta è il migliore.
Eccellente che questo passa attraverso tutti i Manifesti. – HankCa