best way to version tag a java file

S

steve

Hi,
I'm trying to tag a java file ( jar) at compile time, with an incrementing
key.
basically i want to use it for version checking.
I do not want to go to each source file & have to reenter a key as it is a
pain.

any ideas how i might solve this?

steve
 
J

Jacob

steve said:
I'm trying to tag a java file ( jar) at compile time, with an incrementing
key.
basically i want to use it for version checking.
I do not want to go to each source file & have to reenter a key as it is a
pain.

any ideas how i might solve this?

I create a build file as part of the build process and
include it in the jar. The counter ("buildno") is copied
from a separate file and this file is incremented after
the copying so it holds the buildno for next build.

The build file might include other information such as
build date, platform, operator etc. Inside my program I
use the information to pouplate a "Version" instance
which I can use for various purposes.

I use "make" for the build process and shell scripts for
creating the build file as described above. I am sure you
can acheive the same with "Ant" if that is your preference.
 
R

Rob Shepherd

steve said:
Hi,
I'm trying to tag a java file ( jar) at compile time, with an incrementing
key.
basically i want to use it for version checking.
I do not want to go to each source file & have to reenter a key as it is a
pain.

any ideas how i might solve this?

steve
You could add some meta data to the Jar files manifest.

Rob
 
R

Rogan Dawes

Rob said:
You could add some meta data to the Jar files manifest.

Rob

What is the best way to get that information out of the manifest, from
your program?


e.g. I have the following ant clause when creating my jar:

<target depends="compile" name="build">
<jar basedir="${classes}" jarfile="${jarname}">
<manifest>
<attribute name="Main-Class" value="${mainclass}"/>
<attribute name="Built-By" value="${user.name}"/>
<section name="common">
<attribute name="Implementation-Title" value="common"/>
<attribute name="Implementation-Version" value="${version}"/>
<attribute name="Implementation-Vendor" value="OWASP"/>
</section>
</manifest>
</jar>
</target>

But what is the best way to access the manifest from within the program
itself?

Rogan
 
J

Jacob

Rogan said:
What is the best way to get that information out of the manifest, from
your program?

The manifest file is like any file other in your .jar,
and even though you can access it through the Manifest
class API (which is horrible if I recall correctly), you
can simply read it as any text file:

InputStream stream = getClass().getResourceAsStream("/META-INF/MANIFEST.MF");
BufferedReader reader = new BufferedReader (new InputStreamReader (stream));

String line = reader.readLine();
while (line != null) {
if (line.startsWith ("Version:"))
// do this
else if ...
// do that

line = reader.readLine();
}

The reason I dislike using the manifest file for this
purpose is its weird format "<key>: <value>" instead
of the more natural Properties format "<key> = <value>"
which would have made it easier to manipulate using the
Properties API.
 
R

Rogan Dawes

Jacob said:
The manifest file is like any file other in your .jar,
and even though you can access it through the Manifest
class API (which is horrible if I recall correctly), you
can simply read it as any text file:

InputStream stream =
getClass().getResourceAsStream("/META-INF/MANIFEST.MF");
BufferedReader reader = new BufferedReader (new InputStreamReader
(stream));

String line = reader.readLine();
while (line != null) {
if (line.startsWith ("Version:"))
// do this
else if ...
// do that

line = reader.readLine();
}

The reason I dislike using the manifest file for this
purpose is its weird format "<key>: <value>" instead
of the more natural Properties format "<key> = <value>"
which would have made it easier to manipulate using the
Properties API.

Cool, thanks!

Looks like the other way (using Manifest) is like:

Manifest manifest = new
Manifest(getClass().getResourceAsStream("/META-INF/MANIFEST.MF"));
Attributes att = manifest.getAttributes("common");
String version = att.getValue(Attributes.Name.IMPLEMENTATION_VERSION);

Which (although untested) does not look too bad.

Last question:

How do I determine if I am running from a Jar or not? I don't want to
use some manifest that is lying around on the filesystem if I am running
unpackaged classes.

Could I then rather use:

URL url = getClass().getResource("/META-INF/MANIFEST.MF");
if (url.toString().startsWith("jar:")) {
Manifest manifest = new Manifest(url.getInputStream());
// etc
}

Rogan
 
J

Jacob

Rogan said:
Last question:

How do I determine if I am running from a Jar or not? I don't want to
use some manifest that is lying around on the filesystem if I am running
unpackaged classes.

Not "some" manifest file, but the exact same as you intend
to pack with your jar.

You probably have a code source tree and (preferrable) a code
destination (.class) tree on your system. In your source tree,
make a META-INF/ directory along with your com/some/company
directories and put the manifest file there. In your build script,
make sure it is copied to the same location in your destination
tree. Now you can access the manifest file through the (destination
tree) classpath as if it was in a .jar.

When you bundle your .jar, pick the same manifest file from your
source tree.

At least I would prefer this solution to one that differentiate
path of logic depending on program runs as .jar or not.
 
S

Shane Petroff

Jacob said:
Not "some" manifest file, but the exact same as you intend
to pack with your jar.

Am I missing something? Why not

// will throw an IOException if JAR_NAME doesn't exist
final JarFile jf = new JarFile(JAR_NAME);

final Manifest manif = jf.getManifest();
final Attributes attr = manif.getMainAttributes();
...

if you catch the IOException, read it from a predefined spot in the file
system as Jacob says.
 
O

Oscar kind

Rogan Dawes said:
Rob Shepherd wrote:

What is the best way to get that information out of the manifest, from
your program?


e.g. I have the following ant clause when creating my jar:

<target depends="compile" name="build">
<jar basedir="${classes}" jarfile="${jarname}">
<manifest>
<attribute name="Main-Class" value="${mainclass}"/>
<attribute name="Built-By" value="${user.name}"/>
<section name="common">
<attribute name="Implementation-Title" value="common"/>
<attribute name="Implementation-Version" value="${version}"/>
<attribute name="Implementation-Vendor" value="OWASP"/>
</section>
</manifest>
</jar>
</target>

But what is the best way to access the manifest from within the program
itself?

Package myPackage = getClass().getPackage();
String title = myPackage.getImplementationTitle();
String vendor = myPackage.getImplementationVendor();
String version = myPackage.getImplementationVersion();
 

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
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top