Re: Getting a property from MANIFEST.MF?

A

Arne Vajhøj

Spud said:
My app needs to know what version it is, for the purpose of dumping it
in log files, etc.. The version is dynamically created at build time.

I'm thinking that the best way to do this is to put the app version in
MANIFEST.MF.

The trouble is that at runtime, I call

InputStream in =
MyClass.class.getResourceAsStream("/META-INF/MANIFEST.MF");

and it returns a reference to a MANIFEST.MF which is in some other jar
file (looks like some system jar). This makes sense; the classloader for
the current class probably loads classes from other jars as well, and
there are a lot of manifests on the classpath.

So, how do I specify which manifest to fetch?

Or is there a better way to do this? This has got to be a common
requirement...

Find the jar file your class is loaded from and read the manifest
from that using java.util.jar classes.

Arne
 
M

Mark Space

Arne said:
Spud wrote:
Find the jar file your class is loaded from and read the manifest
from that using java.util.jar classes.

It irritates me that Java often makes it difficult to do things that are
obviously necessary, like accessing attributes from your own jar file.
Here's what I came up with, although it only works on JARs run from
disk, I doubt it'll work over a network, which I can't test anyway right
now.


package jartest;

import java.io.IOException;
import java.net.URL;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

public class Main
{
public static void main( String[] args ) throws IOException
{
JarFile jf = findJarfile( Main.class );
if( jf != null ) {
Manifest manifest = jf.getManifest();
Map<String, Attributes> entries = manifest.getEntries();
System.out.println( "Entries: " + entries.size() + "\n" +
entries );
}
}

private static JarFile findJarfile( Class<?> c ) throws IOException
{
String classname = c.getName();
classname = "/" + classname.replaceAll( "\\.", "/" ) + ".class";
URL url = c.getResource( classname );
//System.out.println( "URL = " + url );
String urlString = url.toString();
if( urlString.startsWith( "jar:" ) ) {
String filename = urlString.substring( 9,
urlString.indexOf( '!' ) );
JarFile jarfile = new JarFile( filename );
return jarfile;
// Manifest manifest = jarfile.getManifest();
// Map<String, Attributes> entries = manifest.getEntries();
// System.out.println( "Entries:\n"+ entries );
}
else {
return null;
// System.out.println( "Class is not associated with a JAR." );
}
}
}


I dislike how much string mangling I have to do to get this. Does Sun
provide a method somewhere's to do this? I can't find it.
 
A

Arne Vajhøj

Mark said:
It irritates me that Java often makes it difficult to do things that are
obviously necessary, like accessing attributes from your own jar file.
Here's what I came up with, although it only works on JARs run from
disk, I doubt it'll work over a network, which I can't test anyway right
now.
JarFile jf = findJarfile( Main.class );
if( jf != null ) {
Manifest manifest = jf.getManifest();
Map<String, Attributes> entries = manifest.getEntries();
System.out.println( "Entries: " + entries.size() + "\n" +
entries );
}
}

private static JarFile findJarfile( Class<?> c ) throws IOException
{
String classname = c.getName();
classname = "/" + classname.replaceAll( "\\.", "/" ) + ".class";
URL url = c.getResource( classname );
//System.out.println( "URL = " + url );
String urlString = url.toString();
if( urlString.startsWith( "jar:" ) ) {
String filename = urlString.substring( 9, urlString.indexOf(
'!' ) );
JarFile jarfile = new JarFile( filename );
return jarfile;
// Manifest manifest = jarfile.getManifest();
// Map<String, Attributes> entries = manifest.getEntries();
// System.out.println( "Entries:\n"+ entries );
}
else {
return null;
// System.out.println( "Class is not associated with a JAR." );
}
}
}
I dislike how much string mangling I have to do to get this. Does Sun
provide a method somewhere's to do this? I can't find it.

Maybe:

Foobar.class.getProtectionDomain().getCodeSource().getLocation()

Arne

PS: But I used to do it the same way as you.
 
T

Tom Anderson

It irritates me that Java often makes it difficult to do things that are
obviously necessary, like accessing attributes from your own jar file.

This particular case also irritates me *immensely*. I had a case where i
wanted to programmatically inspect the version of a library i'd loaded;
the information was there in the manifest, but i couldn't see any way to
get at it.
Here's what I came up with, although it only works on JARs run from
disk, I doubt it'll work over a network, which I can't test anyway right
now.

Thanks! I'll see if i can apply this to my situation.

tom
 
M

Mark Space

Here's a version I cooked up later that uses URL instead of JarFile. I
still haven't tested it on other than files on my hard drive. I have no
idea if it'll actually work over a network, or under what circumstances.


private static JarInputStream findJar( Class<?> c )
throws IOException
{
String classname = c.getName();
classname = "/" + classname.replaceAll( "\\.", "/" ) + ".class";
URL url = c.getResource( classname );
String urlString = url.toString();
if( urlString.startsWith( "jar:" ) ) {
String jarname = urlString.substring( 4, urlString.indexOf(
'!' ) );
URL finalurl = new URL( jarname );
JarInputStream jis = new JarInputStream(
finalurl.openStream() );
return jis;
}
else {
return null;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top