Wednesday, November 24, 2004

Installing Java on FreeBSD

In January I explained how I installed the java/jdk14 port on FreeBSD 5.2. Today I installed the java/jdk14 port on one 5.3 RELEASE system, janney, and then used packages built during the install process to install the JDK on my 5.3 RELEASE laptop, orr.

The FreeBSD project cannot distribute packages of the latest Java software due to Sun's licensing restrictions. (Really old 1.3.1 binary packages are offered from the FreeBSD Foundation.) I can create my own packages for personal use as I have read and accepted Sun's licenses. I cannot redistribute those packages for others to use.

First I ensured my ports tree was updated. Next I placed the necessary archives for the installation in /usr/ports/distfiles. These included:


The first is available at The second is available as the J2SE v 1.4.2_06 JRE. The next three are available on the
Java 2 Platform, Standard Edition (J2SE) Sun Community Source License - Download
page. The last is posted as the J2SE v 1.4.2_06 SDK.

I also knew I had to have linprocfs already loaded. This meant that my /etc/fstab needed this entry:

linprocfs /compat/linux/proc linprocfs rw 0 0

I found that the best way to handle this was to add the entry to /etc/fstab and then reboot the system. I tried to manually follow these instructions to enable linprocfs:

kldload linprocfs
mount /compat/linux/proc

This did not work for me, since there was no /compat/linux/proc directory. I ended up creating a /compat/linux/proc directory by hand. (To be completely honest I lost track of how I ended up getting linprocfs to work, since my notes are blank at that point. I'd be interested in hearing if others had similar problems. I didn't seem to have any issues on 5.2 in January.)

Matthew Seaman's freebsd-java post explains that "in order to build JDK 1.4.2 you need a working JDK 1.4.x to compile everything. As things stand, that means at some point you have to use a Linux JDK to do an initial compilation."

A preview of what happens once you start the build process confirms Matthew's assertion:

===> jdk-1.4.2p6_6 depends on file: /usr/local/linux-sun-jdk1.4.2/bin/javac -
not found
===> Verifying install for /usr/local/linux-sun-jdk1.4.2/bin/javac in
Warning: This JDK may be unstable. You are advised to use the native
FreeBSD JDK, in ports/java/jdk14.

This Java VM will attempt to obtain some system information by
accessing files in linux's procfs. You must install the Linux
emulation procfs filesystem for this to work correctly. The JVM
will exhibit various problems otherwise. This can be accomplished
by adding the following line to your /etc/fstab file:

linprocfs /compat/linux/proc linprocfs rw 0 0

and then, as root, executing the commands:
kldload linprocfs
mount /compat/linux/proc

===> Vulnerability check disabled
===> Extracting for linux-sun-jdk-
>> Checksum OK for j2sdk-1_4_2_06-linux-i586.bin.

Matthew continues: "Once you've compiled the JDK one time using the Linux emulation, you can discard the linux bits and use your native JDK to compile any updates... You can also take an installed native JDK 1.4.2 and create a package out of it." That's what we're going to do. Building java/jdk14 on host janney requires Linux emulation, but the package on laptop orr won't.

To start the build process I entered the /usr/ports/java/jdk14 directory and ran this command:

janney:/usr/ports/java/jdk14# make package-recursive DISABLE_VULNERABILITIES=true

The 'package-recursive' directive tells the make process to create the java/jdk14 package, as well as packages for all of the java/jdk14 dependencies. When the process is finished, you'll have packages (.tbz files) in /usr/ports/packages/All.

The 'DISABLE_VULNERABILITIES=true' directive disables vulnerability checking provided via the portaudit tool. I generally do not advocate this step because you are potentially installing software with vulnerabilities. For example, I originally executed 'make package-recursive' and had this result:

===> jdk-1.4.2p6_6 depends on file: /usr/X11R6/lib/ - not found
===> Verifying install for /usr/X11R6/lib/ in /usr/ports/x11-toolkits
===> open-motif-2.2.3 has known vulnerabilities:
>> xpm -- image decoding vulnerabilities.
>> Please update your ports tree and try again.
*** Error code 1

Stop in /usr/ports/x11-toolkits/open-motif.
*** Error code 1

Stop in /usr/ports/java/jdk14.

A visit to shows a new feature -- the "skull icon" indicating a security vulnerability in the desginated version of x11-toolkits/open-motif. Although OpenMotif 2.2.4, patching the hole, is available, it has not been integrated into the FreeBSD ports tree. According to the portaudit and VuXML reports, X11R6.8.1 fixes the problem. A look through the freebsd-x11 mailing list shows that a port of xorg 6.8.1 is in the works but not finished.

There's a second security issue to consider. Sun released an advisory warning customers to not use the "SDK and JRE [versions] 1.4.2_05 and earlier, all 1.4.1 and 1.4.0 releases, and [version] 1.3.1_12 and earlier." This follows a post to full-disclosure, publicizing the issue. FreeBSD Java patch set developer Greg Lewis committed an update marking the java/jdk14 port "forbidden" when building the browser plug-in because of this vulnerability. In fact, you'd see this warning even if yo do disable vulnerability checks:

===> jdk-1.4.2p6_6 is forbidden: Vulnerabilities in the browser plugin.

In an email exchange Greg assured me that "vulnerability exists in the current patchset and will do so until we find a fix for it." Besides invoking 'DISABLE_VULNERABILITIES=true', one could also build java.jdk14 with 'MINIMAL=true', as that directive says 'don't build/install mozilla java plugin, javaws and JDK demos'.

Since I was deploying Java to support some applications, and not run in a browser, I wasn't worried about reading either malicious images (affecting xpm) or applets (affecting the Java JRE).

When the build process is done, execute 'make install' to install java/jdk14.

If you're sucessful, you'll find jdk-1.4.2p6_6.tbz plus other packages in /usr/ports/packages/All. I chose to install these on my laptop my NFS mounting /usr/ports from build server janney as /mnt on laptop orr:

orr:/root# mount -t nfs janney:/usr/ports /mnt
orr:/root# mount | grep janney
janney:/usr/ports on /mnt (nfs)

Now I could install the package and its dependencies on orr:

orr:/root# pkg_add -v /mnt/packages/All/jdk-1.4.2p6_6.tbz

A successful installation can be checked with this command:

orr:/root# java -version
java version "1.4.2-p6"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-p6-root_24_nov_2004_10_37)
Java HotSpot(TM) Client VM (build 1.4.2-p6-root_24_nov_2004_10_37, mixed mode)

I like this method of building time-intensive, complicated ports elsewhere (on more robust systems) and then installing them as packages via NFS on end-user systems. Had a precomplied package been available from the FreeBSD project or elsewhere, I would have used that. (That's how I installed, another bear to compile from source.) This system works well when you really do need to "roll your own." Thankfully the FreeBSD ports tree simplifies that process.


tweedledeetweedledum said...
This comment has been removed by a blog administrator.
Anonymous said...

Hi, I'm using FreeBSD 6.0 and regarding linuxproc:
mount /compat/linux/proc line gives error, what I did was:
ln -s /usr/compat /compat
because compat is under /usr dir.
Then mount.

Hope this help.

dghnfgj said...
This comment has been removed by a blog administrator.