23 October 2014

Creating a RPM From the Java JDK Tar File

I have been doing some work with Cloudera Hadoop recently, and as part of building a cluster I took the opportunity to automated it using Puppet.

For Cloudera, pretty much all of the setup is done via RPMs and config files, which are easily deployed with Puppet, but there was one initial step that did not have an RPM available - the specific Java version that needs to be installed.

Java is available as a download from Oracle as a tar.gz file - you can extract the tar file anywhere on your system and point your PATH at the extract and Java will work. I decided it would be interesting to turn the tar file downloaded from Oracle into an RPM that is easily deployed from Puppet.

Step 1 - Understand How To Build an RPM

Building an RPM is pretty simple using the rpmbuild command. By default, there is a directory structure in /root/rpmbuild and inside it are several directories:

  • BUILD - This is where the expanded source goes, ie the result of untarring the Java archive
  • BUILDROOT - This is where the built package is deployed
  • RPMS - The final RPM will be here after the build process completes
  • SOURCES - This is where source code goes, in this case the tar.gz file downloaded from Oracle
  • SPECS - This is where the spec file that controls the RPM build is stored
  • SRPMS - If your build also produces a source RPM, it will be stored here.

BUILDROOT is interesting - imagine it is like an empty root file system. If you need to compile source code as part of your RMP build (using the traditional configure, make, make install sequence), you should set the --prefix parameter to configure $RPM_BUILD_ROOT/usr/local - in this way, your package will be installed into $BUILD_ROOT/usr/local and will not affect anything else installed on your machine.

When the RPM is built, rpmbuild will grab all the files inside $RPM_BUILD_ROOT and strip the $RPM_BUILD_ROOT off, leaving you with an RPM that puts the files in the correct place.

Step 2 - Decide On Install Location

Hadoop wants Java to be installed in /usr/java, eg:


With a symlink /usr/java/default pointing at the active Java version.

Step 3 - Create a Spec File

The spec file is where you outline how to turn your sources into a working build, and also list out the files that should be included in the RPM. Create the file jdk-7u55-linux-x64.spec in the SPECS directory containing:

Summary: Java JDK
Name: javajdk
Version: 1.7.0
Release: 55
Group: Software Development
Distribution: Java 7 for RedHat Linux
Vendor: Oracle
Packager: Stephen ODOnnell
License: GPL
# Skip autogenerating RPM dependencies
AutoReqProv: no

Java JDK packaged as an RPM

rm -rf $RPM_BUILD_DIR/jdk%{version}_%{release}
rm -rf $RPM_BUILD_ROOT/*
tar zxf $RPM_SOURCE_DIR/jdk-7u55-linux-x64.tar.gz -C $RPM_BUILD_DIR


mkdir -p $RPM_BUILD_ROOT/usr/java
cp -r $RPM_BUILD_DIR/jdk%{version}_%{release} $RPM_BUILD_ROOT/usr/java/


ln -s /usr/java/jdk%{version}_%{release} /usr/java/default

The prep step simply untars the source code and copies it intop the BUILD_DIR.

Normally the build step is where you would compile the source using make etc, but in this case that isn't necessary.

The install step is generally where you would run the make install command, but in this case, we just copy the contents of the BUILD_DIR into the BUILD_ROOT.

The files step gathers up all the files you want to be included in the RPM - notice that you do not include the RPM_BUILD_ROOT prefix at the start of file paths - rpmbuild is smart enough to know where to file the files.

The final step in this RPM is the post step - this is executed at the end of RPM installation and creates the symlink we require.

Step 4 - Create the RPM

$ cd /root/rpmbuild/SPECS
$ rpmbuild -ba jdk-7u55-linux-x64.spec

The resulting RPM will be generated in /root/rpmbuild/RPMS/x86_64/javajdk-1.7.0-55.x86_64.rpm and can be installed as usual:

rpm -ivh /root/rpmbuild/RPMS/x86_64/javajdk-1.7.0-55.x86_64.rpm
blog comments powered by Disqus