As the maintainer of the java/openjdk6 port for FreeBSD I recently took on the challenge of upgrading the java/openjdk6 port from b16 to the newly released b17. I’ve decided to blog about, partly to document my efforts to review when b18 comes out, but also to share the process with all that are interested.

I started by downloading the new zip from http://download.java.net/openjdk/jdk6/, and updating the distinfo and Makefile for the port to use the b17 bundle.

Next I went to extract and apply patches. I got a weird message during the extraction process that the hotspot/linux/Makefile didn’t exist. This seemed unusual at first, but it turns out there is a post-extract section in the ports Makefile that was copying and running sed expressions, to create bsd files from linux versions. A couple of directories and files needed to be removed, then I moved on to the patching process.

I optimistically tried to patch but patch died complaining about a hunk ordering mismatch. I tried to work with the single patch-set file for several minutes before deciding to take a different approach and split the patch. I separated the single patch file so that every file that required a patch had its own patch file. This allowed me to deal with patches on a file by file basis. I found splitpatch.rb at http://www.clearchain.com/~benjsc/download/splitpatch/splitpatch.rb, and slightly modified the output filename, and quickly got the job done.

Next I seperated patches that applied cleanly from patches that had errors using the following command and parsing the results by hand.

find /usr/ports/java/openjdk6/files/brian1/ -name \*patch\* -print -exec bash -c "patch -lsC < {};" ';' 2&1; | less

Of 288 total files patched, 221 patches merged successfully and 67 patches failed. I started addressing the failed patches by categorizing them. There where 34 makefiles, 13 build files, 12 src files, 6 agent files, and 2 uncategorized files.

My plan was to apply all the clean patches, then hand merge the rest, build, then recreate the patch-set at the very end. I started by making a non-patched work directory using the command make extract. Then I created two copies of this directory called orig and work-progress. I would perform all work inside of work-progress and copy any modified files into the work directory to test my changes. I planned to use orig for creating the patch-set from my modified work-progress copy.

If I made numerous changes, or wanted to verify the entire patch I would start with a fresh copy of my work-progress directory.

# equivalent of a make clean
rm -rf work && cp -Rp work-progress work

There was one file that proved to be a pain to patch. hotspot/src/os/bsd/vm/os_bsd.cpp, would not patch with the following error message.

patch: **** misordered hunks! output would be garbled

I started hand merging the patch, and after 15 minutes, I thought to myself there had to be a better way. I decided to split the patch into individual hunks using the splitpatch.rb script, and apply each hunk individually. It worked like a charm, and only one of the hunks had to be hand merged. I did have to instruct patch as to which file these hunks applied to be passing hotspot/src/os/bsd/vm/os_bsd.cpp as an extra argument.

However compiling this file resulted in an error. Some hunks were applied in obviously incorrect locations. Turns out the default fuzz factor of two, was the culprit. I reapplied the patch with a fuzz factor of 0, and this time three hunks failed and needed to be applied by hand. I bet if I tried a fuzz factor of 0, with the original non-split-by-hunk patch that it would have succeeded with the three rejects.

There were lots of small errors that occurred during the building process. All of them were very minor and required small simple changes. Where error lead my to applying patches for PR #138348 and PR #139452. One thing I found very handy for speeding up the porting process was setting the BUILD_ MAKE_ENV options inside the ports Makefile to only compile one subproject at a time.

#default BUILD_
BUILD_CORBA=true \
BUILD_JAXP=true \
BUILD_JAXWS=true \
BUILD_HOTSPOT=true \
BUILD_MOTIF=true \
BUILD_JDK=true
#only build the hotspot
BUILD_CORBA=false \
BUILD_JAXP=false \
BUILD_JAXWS=false \
BUILD_HOTSPOT=true \
BUILD_MOTIF=false \
BUILD_JDK=false

I finally got a clean building work-progress directory after making a lot of little tiny fixes and reapplying some patches.

Below is the script I used to create the patchset from my modified source:

#!/bin/sh

rm -rf /usr/ports/java/openjdk6/work-pristine;
cp -rp /usr/ports/java/openjdk6/work-progress /usr/ports/java/openjdk6/work-pristine;
cd /usr/ports/java/openjdk6/work-pristine;
find ./ -name \*.rej -exec rm '{}' ';'
find ./ -name \*.orig -exec rm '{}' ';'
find ./ -name \*sC -exec rm '{}' ';'
diff -uNr ../orig/ ./ > ../files/make1/patch-set

You can gain early access to this port by downloading it from:
http://www.getsnappy.com/downloads/openjdk6-b17-pr2.tar.gz

To install:

cd /usr/ports/java
tar -xjf <path_to_tar_bundle>/openjdk6-b17-pr2.tar.gz
cd openjdk6-b17
make

Pre Release 2 features these fixes:

  • no more ugly fonts!
  • locale data is now correct
  • supports building on 9.0 current
  • include fastdebug build options creates a mirrored /usr/local/openjdk6-fastdebug installation