Problems reading custom attributes from manifest file

M

Manish Hatwalne

I have added custom attributes to the manifest file (via ANT task), and I am
reading it in my code.
However, the custom attributes are missing when I read this manifest file in
the code. I have opened the jar with WinZip and have ensured that the
MANIFEST.MF file indeed contain these attributes, however the attributes my
code lists are -

Manifest-Version=1.0
Implementation-Title=Java Runtime Environment
Implementation-Vendor=Sun Microsystems, Inc.
Specification-Version=1.4
Specification-Title=Java Platform API Specification
Name=javax/swing/JApplet.class
Created-By=1.4.0_01 (Sun Microsystems Inc.)
Java-Bean=True
Implementation-Version=1.4.0_01
Specification-Vendor=Sun Microsystems, Inc.

I have no clue from where name attribute got inserted. The intended manifest
file is -

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.5.4
Created-By: 1.4.0_01-b03 (Sun Microsystems Inc.)
Implementation-Title: XXXXXXX
Built-By: manish
Build-Date: May 20 2004
Date-Format: yyyy/MM/dd HH:mm:ss
Major-Version: 0
Minor-Version: 50
Version: 0.50
Build-Number: 64

What could be the reason?

- Manish
 
C

Chris Uppal

Manish said:
Manifest-Version=1.0
Implementation-Title=Java Runtime Environment
Implementation-Vendor=Sun Microsystems, Inc.
Specification-Version=1.4
Specification-Title=Java Platform API Specification
Name=javax/swing/JApplet.class
Created-By=1.4.0_01 (Sun Microsystems Inc.)
Java-Bean=True
Implementation-Version=1.4.0_01
Specification-Vendor=Sun Microsystems, Inc.

This looks like the manifest file from the rt.jar file from a 1.4.0 JDK. I.e.
you are probably finding the manifest from the wrong jar file.

-- chris
 
M

Manish Hatwalne

This looks like the manifest file from the rt.jar file from a 1.4.0 JDK. I.e.
you are probably finding the manifest from the wrong jar file.
Is it???
In that case how can I correctly read the MANIFEST.MF file from my jar? I
have used -
this.getClass().getResourceAsStream("/META-INF/MANIFEST.MF");

- Manish
 
A

Andrew Thompson

...
Is it???

I think Chris is right, I recall from my
experiments with classloaders reading that
the parent classloader was used before any
custom classloader, and it checked the core
..jar's first(?).
In that case how can I correctly read the MANIFEST.MF file from my jar?

You might get the URL of an unique resource
in your jar (e.g. '/distinct_marker.txt') and use that
URL to build your URL to the MANIFEST.MF..
 
M

Manish Hatwalne

Andrew Thompson said:
JDK.

I think Chris is right, I recall from my
experiments with classloaders reading that
the parent classloader was used before any
custom classloader, and it checked the core
.jar's first(?).


You might get the URL of an unique resource
in your jar (e.g. '/distinct_marker.txt') and use that
URL to build your URL to the MANIFEST.MF..

Tried this as well, but it still returns empty attributes Map. I don't know
WHY???? :(
This is what I tried -


URL jarURL =
this.getClass().getResource("/com/mypackage/core/Application.class");
System.out.println("URL - " + jarURL ); //returns valid URL
JarURLConnection jurlConn = (JarURLConnection)jarURL.openConnection();
Manifest mf = jurlConn.getManifest();
Map attributes = mf.getEntries();
System.out.println("\n\n" + attributes); //simply prints blank map
 
M

Manish Hatwalne

OK!
This is a standalone sample code that I wrote, this doesn't work either.
What can I do to make it work???

(1) manifest file (MANIFEST.MF)
=======================
Manifest-Version: 1.0
Created-By: 1.4.0_01-b03 (Sun Microsystems Inc.)
Main-Class: myprojects.readmanifest.ReadManifest
Built-By: manish

Java Code
==============
package myprojects.readmanifest;

import java.util.*;
import java.util.jar.*;
import java.net.*;

public class ReadManifest
{

public static void main(String args[])
{
System.out.println("Starting ReadManifest...");
new ReadManifest().listManifestAttributes();
}

public void listManifestAttributes()
{
try{
URL jarURL =
this.getClass().getResource("/myprojects/readmanifest/ReadManifest.class");
System.out.println(jarURL);
JarURLConnection jurlConn = (JarURLConnection)jarURL.openConnection();
Manifest mf = jurlConn.getManifest();
Map attributes = mf.getEntries();
System.out.println("\n\n" + attributes); //simply prints blank map
System.out.println(attributes.get("Built-By")); //prints null
System.out.println(mf.getAttributes("Built-By")); //prints null
}
catch(Exception e){
e.printStackTrace();
}
}
}

Then I compile this and jar it using following comaand from the directory
which contains the classes and manifest file
jar -cvfm readmanifest.jar MANIFEST.MF myprojects*

Verified that the manifest file contained in jar is the correct manifest
file. And run it as -
java -jar readmanifest.jar

The output I get is -
Starting ReadManifest...
jar:file:/D:/Java/ReadManifest/classes/readmanifest.jar!/myprojects/readmani
fest/ReadManifest.class


{}
null
null

Now what could be the reason???

Thanks,
- Manish
 
M

Michael Rauscher

Hi Manish,

Manish said:
OK!
This is a standalone sample code that I wrote, this doesn't work either.
What can I do to make it work???

URL jarURL =
this.getClass().getResource("/myprojects/readmanifest/ReadManifest.class");
System.out.println(jarURL);
JarURLConnection jurlConn = (JarURLConnection)jarURL.openConnection();

The URL points to the entry /myprojects/readmanifest/ReadManifest.class.
Next, you treat the class file like a manifest file. As the class file
doesn't contain manifest entries, you get an empty list.

Again, you have to strip the
!/myprojects/readmanifest/ReadManifest.class part from the URL in order
to make the URL pointing to JAR file.

Bye
Michael
 
M

Manish Hatwalne

Michael Rauscher said:
Hi Manish,

(JarURLConnection)jarURL.openConnection();

The URL points to the entry /myprojects/readmanifest/ReadManifest.class.
Next, you treat the class file like a manifest file. As the class file
doesn't contain manifest entries, you get an empty list.

Again, you have to strip the
!/myprojects/readmanifest/ReadManifest.class part from the URL in order
to make the URL pointing to JAR file.

Nah!
That wasn't the problem.

The problem was with "Map attributes = mf.getEntries();"
I replaced it with following code and it worked!!! :)

URL jarURL =
this.getClass().getResource("/myprojects/readmanifest/ReadManifest.class");
JarURLConnection jurlConn = (JarURLConnection)jarURL.openConnection();
Manifest mf = jurlConn.getManifest();
Attributes attr = mf.getMainAttributes();
System.out.println(attr.getValue("Built-By")); //prints manish

Thanks for all the help nevertheless!!!!

- Manish
 
M

Manish Hatwalne

Guess (my) entire confusion was due to the javadocs for these tow methods of
Manifest class. IMHO, they are misleading.

public Map getEntries()
Returns a Map of the entries contained in this Manifest. Each entry is
represented by a String name (key) and associated Attributes (value).

Returns:
a Map of the entries contained in this Manifest

public Attributes getAttributes(String name)Returns the Attributes for the
specified entry name. This method is defined as:
return (Attributes)getEntries().get(name)

Parameters:
name - entry name
Returns:
the Attributes for the specified entry name


They almost got me to believe that this Map would indeed contain the
attributes.
Anyway, thanks to all those who helped.

- Manish




"Manish Hatwalne" wrote in message news:[email protected]...
 
M

Michael Rauscher

Manish said:
Nah!
That wasn't the problem.

The problem was with "Map attributes = mf.getEntries();"
I replaced it with following code and it worked!!! :)

Nice (and interesting) to see, that JarURLConnection/Manifest is smart
enough to handle this scenario :)

Bye
Michael
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top