//
you're reading...
General, Java/Cloud

My Experience building JDK1.6 from source

I have hacked easily into a running JVM to achieve my end goals. I have sieved through the code to understand how exactly the code is working to understand where hooks can be added to achieve a final result. I have in-fact easily reverse engineered the JVM binary also to understand how it works. Yet, when I sat down to build my own version of the JVM I found that it was a much tougher problem than others. I write this blog in the hope that it will help another soul in agony trying to do what I did and also as a reminder to me if I try to do this all over again on a fresh machine.

I compiled the source on debian linux (lenny distribution) with GCC 4.3 version. Definitely it was worth all the trouble to compile it and see it running successfully. The instructions for build provided with the source code pretty is cryptic and does not address what should be done when an error occurs.
I downloaded the source from here, the version I have built is jdk-6u2-fcs-src-b05-jrl-22_jun_2007.jar

When you run

“make dev-sanity”

once you setup the system according to the README-builds.html file you will find it will give you a set of errors:

“ERROR: You do not have a valid DEVTOOLS_PATH setting.
Please check your access to
/java/devtools/linux/bin/
and/or check your value of ALT_DEVTOOLS_PATH.”

This means that you need to set the ALT_DEVTOOLS_PATH to a location that has the zip and unzip commands. So, set this to /usr/bin.

“ERROR: You do not have a valid GCC29_COMPILER_PATH setting.
Please check your access to
/java/devtools/linux/gcc29/usr/
and/or check your value of ALT_GCC29_COMPILER_PATH.
This will affect you if you build the plugin target.”

You can get over this by pointing ALT_GCC29_PLUGIN_LIB_PATH to a location where you have a previous version of libjavaplugin_oji.so library.

Even though by doing this the current error will be resolved, you will find later that irrespective it will check for the presence of this library in the location ALT_GCC29_PLUGIN_LIB_PATH/ns7. So create a directory ns7 under the same directory and link this file into that directory.

Later it will also complain that a file called libjavaplugin_nscp_gcc29.so is not present in the ALT_GCC29_PLUGIN_LIB_PATH directory. If you have installed sun JDK as I have you will find this file under jre/lib/i386/libjavaplugin_nscp_gcc29.so. Link this file also into this directory.

“ERROR: You do not have access to valid Mozilla header files.
Please check your access to
/java/devtools/share/plugin/mozilla_headers_18/java/bool.h
and/or check your value of ALT_JDK_DEVTOOLS_DIR, ALT_MOZILLA_HEADERS_PATH,

Do what I may I have not been able to get over this error other than installing the correct package. In debian lenny it is present in the xulrunner-1.9 and xulrunner-dev package. This installs the required header files under /usr/include/xulrunner-1.9/ directory and the required files will be present under the unstable directory. Set the ALT_MOZILLA_HEADERS_PATH to this directory.

But irrespective you need to create the mozilla_headers_18/java directory in here and link it to the unstable/ directory.

“ERROR: You do not have access to the previous java release jre bundles.
Please check your access to
/java/re/j2se/1.5.0/archive/fcs/bundles/linux-i586/jdk-1_5_0-linux-i586.tar.gz
and/or check your value of ALT_PREVIOUS_RELEASE_PATH or ALT_PREVIOUS_JRE_FILE
This will affect you if you build the images target.”

This means you have to set the ALT_BOOTDIR path to the path of your bootstrap JDK installation. Ensure the ALT_BOOTDIR path is the path to this jdk (JAVA_HOME) not the bin.
Once all this is done, the make dev-sanity runs successfully. So the full command will look similar to:

make dev-sanity ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk/ ALT_DEVTOOLS_PATH=/usr/bin ALT_GCC29_PLUGIN_LIB_PATH=/usr/lib/jvm/java-6-sun/jre/plugin/i386/ns7-gcc29 ALT_MOZILLA_HEADERS_PATH=/usr/include/xulrunner-1.9/

Note that the bootdir is the openjdk, while the GCC29 plugin path is from sun JDK.

Now you can run the compilation:

make dev ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk/ ALT_DEVTOOLS_PATH=/usr/bin ALT_GCC29_PLUGIN_LIB_PATH=/usr/lib/jvm/java-6-sun/jre/plugin/i386/ns7-gcc29 ALT_MOZILLA_HEADERS_PATH=/usr/include/xulrunner-1.9/

The –Wconversion flags causes problems, since it flags all conversions as errors, so, remove this from the variable ACCEPTABLE_WARNINGS in gcc.make in the dir hotspot/build/linux/makefiles.

Once these errors are done there will be a deprecated string conversion error, modify all the files to declare the strings as constants, or add the flag -Wno-write-strings to the ACCEPTABLE_WARNINGS to prevent this error.

The ALSA and CUPS are the only packages needs to be the dev packages and not just the binaries. This means you need the appropriate dev packages so that the header files are present. So it needs in debian linux libcups2-dev package and the libsource2-dev packages to be installed.
Once this is done the errors will be fixed and the libjvm.so will be built. But this library will not load and cause a problem

“libjvm.so: unexpected PLT reloc type 0x08 “

This is due to the bug: 6490707
Modify the vm.make file for this in the hotspot/build/linux/makefiles directory to be

“$(LINK_VM) -Wl,–verbose $(LFLAGS_VM) | \ “

from

“$(LINK_VM) -Wl,–verbose $(LFLAGS_VM) 2>&1 > /dev/null | \”

Ensure that this creates the libjvm.so.lds file with the correct data in it. The data in this should be the output of the command:

gcc -m32 -march=i586 -Xlinker -O1 -shared -Wl,–verbose -Xlinker –version-script=mapfile_reorder -Xlinker -soname=libjvm.so -static-libgcc | sed -e ‘/^======/,/^======/!d’ -e ‘/^======/d’ -e ‘s/0\( + SIZEOF_HEADERS\)/ 0x06000000 \1/’

Once this is done, the test_gamma script is run to test the libjvm.so file generated. This will pass or fail based on the bootstrap JDK used. In fact the build instructions say:

“ Note that the Bootstrap JDK can be a newer JDK, and in fact you could make the Bootstrap JDK and the Import JDK (described below) the same. There is some risk in this approach if the Bootstrap JDK you choose happens to be unstable.”

But, this definitely has problems. I tried a bootstrap JDK which is build (1.6.0_22-b04), and the test_gamma script (tests the hotspot libjvm.so file built) kept crashing. This seems to use the jar files etc from the bootstrap JDK and runs the java with this library. If there is a mismatch in the bootstrap classes it crashes. I ended up using openJDK version (6b18-1.8.3-2~lenny1) to get it working after that.

Once done it will compile all forms of hotspot JVM (server/client/hotspot) will compile. After this, j2se will compile. To get this compiled
Change j2se/make/java/hpi/native/Makefile to define HAVE_SIGIGNORE flag, else there will be a duplicate definition of sigignore function. Include this in the Makefile:

OTHER_CPPFLAGS += -DHAVE_SIGIGNORE

Modify other files such as src/solaris/native/sun/awt/awt_dnd.c to declare xerror_code to non-static and other files that complain of duplicate definition.
There will be other compilation errors related to missing libraries based on the dev packages installed some include libX11-dev, libxmu-dev, libxtst-dev, libxl-dev, libxp-dev etc packages that need to be installed.

When the swing files are being compiled, it will complain that the computer.gif file is not present and it does not know how to make it, To get over this error I just said I do not care about icons, do not check for it. This is done in /j2se/make/javax/swing/plaf/Makefile, comment out the line

#MISC_FILES = $(MISC_SWING_FILES)

After this it will ask for the soundbank.gm, pick up the file from the bootstrap jdk and copy into the appropriate directory.
Once this is done deploy will compile. This will give errors related to GetCurrentThread and PostEvent are not functions of nsIThreadManager, and it will complain that nsIRunnable is not a class, so include the nsIRunnable.h in “deploy/src/plugin/share/adapter/common/CNSAdapter_JVMManager.h” file.
Modify the “deploy/src/plugin/share/adapter/common/CNSAdapter_JVMManager.h” file, change the nsIThreadManager to be nsIJVMThreadManager and change the variable m_pThreadManager to be nsIJVMThreadManager. Looks like GetCurrentThread and PostEvent has changed to be in nsIJVMThreadManager rather than nsIThreadManager.

After this it will complain that the msgfmt command is not found. To get this install the po_debconf package needs to be installed for the msgfmt command to be used.

Once done all other errors will be simple fixable errors. Once done it will compile successfully and the java available in control/build. Set the bin directory into the PATH variable and use java and enjoy!!!

Advertisements

Discussion

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: