Sun’s JDK rpm is not RPM compliant due a hack to compress jar files
A developer alerted me that the jdk1.5.0_10 on a test server didn’t work. A simple ‘java -version’ gave the following error:
Error occurred during initialization of VM
java/lang/NoClassDefFoundError: java/lang/Object
Poking around a little under /usr/java/jdk1.5.0_10, I found that rt.jar was missing! This version of JDK is an upgrade to accommodate the 2007 DST changes. Our current version 1.5.0_05 is just one revision older than the up-to-date release (1.5.0_06) . I had problems installing it as a RPM on that particular server and ended up using rpm2cpio to get it in manually. The RPM was from SUN’s own download site.
The same JDK works fine for all other CentOS 4 and Redhat Linux 9 servers where it was installed as RPM. rt.jar is there for sure. I did a simple verification as below on those working servers. Not sure why I did it retrospectively, I am glad I did since it revealed what’s wrong.
$ rpm –verify jdk-1.5.0_10
missing /usr/java/jdk1.5.0_10/jre/lib/charsets.pack
missing /usr/java/jdk1.5.0_10/jre/lib/deploy.pack
missing /usr/java/jdk1.5.0_10/jre/lib/ext/localedata.pack
missing /usr/java/jdk1.5.0_10/jre/lib/javaws.pack
missing /usr/java/jdk1.5.0_10/jre/lib/jsse.pack
missing /usr/java/jdk1.5.0_10/jre/lib/plugin.pack
missing /usr/java/jdk1.5.0_10/jre/lib/rt.pack
missing /usr/java/jdk1.5.0_10/lib/tools.pack
This means the RPM spec file listed these .pack files and had them in the rpm file too. After installation, they are missing on the disk, while their corresponding .jar files show up. It must be some post-installation RPM steps transformed them. Checking on the server that had broken JDK, I found all these .pack files. No surprise there, since rpm2cpio didn’t do any post-installation RPM steps at all.
To be sure such conversion steps did occur, I check the scripts in the RPM, and found this section:
UNPACK_EXE=/usr/java/jdk1.5.0_10/bin/unpack200
if [ -f $UNPACK_EXE ]; then
chmod +x $UNPACK_EXEPACKED_JARS=”lib/tools.jar jre/lib/rt.jar jre/lib/jsse.jar jre/lib/charsets.jar jre/lib/ext/localedata.jar jr
e/lib/plugin.jar jre/lib/javaws.jar jre/lib/deploy.jar”
for i in $PACKED_JARS; do
srcFile=/usr/java/jdk1.5.0_10/`dirname $i`/`basename $i .jar`.pack
dstFile=/usr/java/jdk1.5.0_10/$i
$UNPACK_EXE $srcFile $dstFile
if [ ! -f $dstFile ]; then
printf “Error: unpack could not create %s. Please refer to the Troubleshooting\n” $dstFile
printf “Section of the Installation Instructions on the download page.\n”
exit 1
firm -f $srcFile
doneelse
printf “Error: unpack command could not be found. Please refer to the \n”
printf “TroubleShooting Section of the Installation Instructions on \n”
printf “the download page.\n”
printf “Please do not attempt to install this archive file.\n”
exit 2
fi
I saved this section to a standalone bash script. All is peachy once I ran this pack2jar.sh, a post-installation script.
Search by Google found a bug report regarding disk space calculation for JDK-1.4.1. So, this pack-to-jar hack had been there for a while. Not sure whether the unpack200 was invented for this hack or not. There’s a lot of good compression utilities out there to be used to compress the whole RPM for distribtuion, why bother to reinvent the wheel? Worse is cherry-picking big files to compress broke RPM spec, and still is not as efficient as compress the whole package. Even if only the jar files is of concern, why not open the jar to allow alternative compression algorithm instead of the default zip or zlib. Not sure whether you’d still call this over-engineering ![]()










