HiveBrain v1.2.0
Get Started
← Back to all entries
patternbashMinor

Extracting the classpath entries from a jar file's manifest

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thefilejarmanifestclasspathextractingfromentries

Problem

Sometimes I need to search for dependencies in the classpath entries in the manifest of jar files. A jar manifest with classpaths looks like this:

Manifest-Version: 1.0
Created-By: 1.6.0_29 (Sun Microsystems Inc.)
Class-Path: spring-aop-3.2.0.jar spring-aspects-3.2.0.jar spring-beans
-3.2.0.jar spring-context-3.2.0.jar spring-context-support-3.2.0.jar
spring-core-3.2.0.jar spring-expression-3.2.0.jar spring-instrument-3
.2.0.jar spring-instrument-tomcat-3.2.0.jar spring-jdbc-3.2.0.jar spr
ing-jms-3.2.0.jar spring-orm-3.2.0.jar spring-oxm-3.2.0.jar spring-st
ruts-3.2.0.jar spring-test-3.2.0.jar spring-tx-3.2.0.jar spring-web-3
.2.0.jar spring-webmvc-3.2.0.jar spring-webmvc-portlet-3.2.0.jar


Searching for jars in a manifest is troublesome:

  • Extract the META-INF/MANIFEST.MF file from the jar



  • Re-join the split lines to make searching humanely possible



Step 2 is necessary, because of the line breaks. For example, I won't find "struts" in the above, because the word is broken in the middle.

I use this shell script to make this process easier, I call it jar-manifest-classpath.sh:

#!/bin/bash

if test -d "$TMPDIR"; then
:
elif test -d "$TMP"; then
TMPDIR=$TMP
elif test -d /var/tmp; then
TMPDIR=/var/tmp
else
TMPDIR=/tmp
fi
workdir=$TMPDIR/$(basename "$0")-work-$$

cleanup() {
rm -fr "$workdir"
}

mkdir -p "$workdir"
trap 'cleanup' 1 2 3 15

for jar; do
if ! test -f $jar; then
echo warning: not a file: $jar
continue
fi
[[ $jar = /* ]] || jar=$PWD/$jar
(
cd "$workdir" || exit 1
jar xf "$jar"
sed -ne '/^Class-Path:/,$p' META-INF/MANIFEST.MF | sed -e 's/^Class-Path: //' -e 's/^ //' | tr -d '\n' | tr ' ' '\n'
)
done

cleanup


For a jar file with the manifest as above, this will output:

`spring-aop-3.2.0.jar
spring-aspects-3.2.0.jar
spring-beans-3.2.0.jar
spring-context-3.2.0.jar
spring-context-support-3.2.0.jar
spring-core-3.2.0.jar
spring-expression-3.2.0.jar
spring-instrum

Solution

I would create the trap for cleanup before an action is done that needs cleanup, so change the sequence of commands. Also I would prefer signal names instead of numbers. If you add EXIT to the signal list then cleanup is called when the shell is exited, so you can remove the last line of your script (cleanup)

trap 'cleanup' EXIT SIGHUP SIGINT SIGQUIT SIGTERM
mkdir -p "$workdir"


If the script is called without argument or with-? a usage message should be displayed.

Warnings and error messages should be written to stderr(2) and not to stdout(1). This is Unix standard behaviour for a program. Otherwise you will not see the error message if you pipe the output through a grep command.

Code Snippets

trap 'cleanup' EXIT SIGHUP SIGINT SIGQUIT SIGTERM
mkdir -p "$workdir"

Context

StackExchange Code Review Q#74087, answer score: 8

Revisions (0)

No revisions yet.