How to build and package OpenJDK 8 on Linux

chaimkut edited this page Feb 12, 2017 · 29 revisions

Some pre-requisites are required to build OpenJDK8 on Linux

Build and package pre-requisites

Be sure to have git, mercurial, gcc/g++, make and required libs and some mandatory tools installed. Java 7 should be installed.

Ensure JAVA_HOME env var point to a valid Java 7 location, example for openSUSE 12.2 :

export JAVA_HOME=/opt/obuildfactory/openjdk7
export PATH=$JAVA_HOME/bin:$PATH

You could also define Java 7+ to be use with OBF_JAVA7_HOME env var, ie on Mint 14 :

export OBF_JAVA7_HOME=/usr/lib/jvm/java-7-openjdk-amd64

As there is no more Java 7 on Ubuntu 16.04/Mint 18.x, so you should use openjdk 8, ie :

export OBF_JAVA7_HOME=/usr/lib/jvm/java-8-openjdk-amd64

Ubuntu 16.04 / Mint 18.x

sudo apt-get install git mercurial zip bzip2 unzip tar curl
sudo apt-get install ccache make gcc g++ ca-certificates ca-certificates-java
sudo apt-get install libx11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev
sudo apt-get install libasound2-dev libcups2-dev libfreetype6-dev
sudo apt-get install build-essential ruby ruby-dev
sudo apt-get install openjdk-8-jdk
sudo apt-get install pkg-config
sudo gem install fpm

Ubuntu 14.04 / Mint 17.x

sudo apt-get install git mercurial zip bzip2 unzip tar curl
sudo apt-get install ccache make gcc g++ ca-certificates ca-certificates-java
sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev
sudo apt-get install libasound2-dev libcups2-dev libfreetype6-dev
sudo apt-get install build-essential ruby ruby-dev
sudo apt-get install openjdk-7-jdk
sudo apt-get install pkg-config
sudo apt-get install ruby-dev
sudo gem install fpm

## Ubuntu 12.x-13.x / Mint 14-16

sudo apt-get install git mercurial zip bzip2 unzip tar curl
sudo apt-get install ccache make gcc g++ ca-certificates ca-certificates-java
sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev  
sudo apt-get install libasound2-dev libcups2-dev libfreetype6-dev
sudo apt-get install build-essential ruby-dev pkg-config
sudo apt-get install openjdk-7-jdk 
sudo gem install fpm

openSUSE / SLES

sudo zypper install git-core mercurial zip bzip2 unzip tar 
sudo zypper install ccache make gcc gcc-c++ ca-certificates-cacert ca-certificates-mozilla
sudo zypper install libstdc++-devel alsa-devel cups-devel xorg-x11-devel libjpeg62-devel giflib-devel 
sudo zypper install curl rpm-build gpg
sudo zypper install java-1_7_0-openjdk-devel

CentOS 5/6

sudo yum install git-core mercurial zip bzip2 unzip tar 
sudo yum install ccache make gcc gcc-c++ libstdc++-devel 
sudo yum install alsa-lib-devel cups-devel libX11-devel libXext-devel libXt-devel libXrender-devel libXtst-devel libXi-devel libjpeg-devel giflib-devel freetype-devel
sudo yum install curl rpm-build gpg
sudo yum install java-1.7.0-openjdk-devel

Fedora 16/17

sudo yum install git-core mercurial zip bzip2 unzip tar 
sudo yum install ccache make gcc gcc-c++ 
sudo yum install libstdc++-devel libstdc++-static alsa-lib-devel cups-devel libX11-devel libXext-devel libXt-devel libXrender-devel libXtst-devel libXi-devel libjpeg-devel giflib-devel freetype-devel 
sudo yum install curl rpm-build gpg rpmbuild rpm-sign
sudo yum install java-1.7.0-openjdk-devel

Prepare environment

For example, you want to build OpenJDKs in openjdkathome directory under your home directory.

mkdir ~/openjdkathome
cd ~/openjdkathome
git clone https://github.com/hgomez/obuildfactory.git

Building OpenJDK

Building is activated by XBUILD env var set to true

cd ~/openjdkathome
XUSE_NEW_BUILD_SYSTEM=true XBUILD=true ./obuildfactory/openjdk8/linux/standalone-job.sh

After some minutes you should see this logs :

Creating images/lib/ct.sym
## Finished images (build time 00:00:13)

----- Build times -------
Start 2016-12-21 11:02:53
End   2016-12-21 11:09:50
00:00:18 corba
00:00:16 demos
00:03:04 hotspot
00:00:13 images
00:00:12 jaxp
00:00:17 jaxws
00:02:02 jdk
00:00:26 langtools
00:00:09 nashorn
00:06:57 TOTAL
-------------------------
Finished building OpenJDK for target 'images'
openjdk version "1.8.0-jdk8u152-b00"
OpenJDK Runtime Environment (build 1.8.0-jdk8u152-b00-20161221)
OpenJDK 64-Bit Server VM (build 25.71-b20161221, mixed mode)
openjdk version "1.8.0-jdk8u152-b00"
OpenJDK Runtime Environment (build 1.8.0-jdk8u152-b00-20161221)
OpenJDK 64-Bit Server VM (build 25.71-b20161221, mixed mode)
~/openjdkathome/sources/openjdk8/build/linux-x86_64-normal-server-release/images ~/openjdkathome

You'll find JDK/JRE tarballs under OBF_DROP_DIR/openjdk8

ls -l OBF_DROP_DIR/openjdk8
total 357072
-rw-r--r-- 1 henri henri 165007405 déc.  21 11:11 j2re-image-x86_64-u152-b00-20161221.tar.bz2
-rw-r--r-- 1 henri henri 200625212 déc.  21 11:10 j2sdk-image-x86_64-u152-b00-20161221.tar.bz2

Specifying a version number

By default, the build factory is retrieving the latest version from the OpenJDK mercurial repository. If you want to build a previous update you can use the XUSE_UPDATE env var to build a specific JDK update. For instance to build JDK 1.8.0_u25:

XUSE_NEW_BUILD_SYSTEM=true XBUILD=true XUSE_UPDATE=25 ./obuildfactory/openjdk8/linux/standalone-job.sh

Clean vs Incremental build

By default, build are performed in incremental mode, ie only updated code is recompiled, reducing overall build time.

But experience in OpenJDK show that weird things happens sometimes and it's better to start from scratch and perform a clean build.

To activate clean mode, use XCLEAN env var ie :

cd ~/openjdkathome
XCLEAN=true XUSE_NEW_BUILD_SYSTEM=true XBUILD=true ./obuildfactory/openjdk8/linux/standalone-job.sh

Native Packages

We have 2 ways to build native packages, stock RPM with rpmbuild and DEB/RPM using FPM

To use stock RPM packaging, use XPACKAGE env var ie :

cd ~/openjdkathome
XPACKAGE=true XCLEAN=true XUSE_NEW_BUILD_SYSTEM=true XBUILD=true ./obuildfactory/openjdk8/linux/standalone-job.sh

To activate FPM and so DEB or RPM, also use XUSE_FPM :

cd ~/openjdkathome
XUSE_FPM=true XPACKAGE=true XCLEAN=true XUSE_NEW_BUILD_SYSTEM=true XBUILD=true ./obuildfactory/openjdk8/linux/standalone-job.sh

Sample on Mint 18 (DEB) :

j2sdk-image/include/linux/jawt_md.h
Setting workdir {:workdir=>"/tmp", :level=>:info}
Setting from flags: category=language {:level=>:info}
Setting from flags: description=OpenJDK 8 native package {:level=>:info}
Setting from flags: epoch= {:level=>:info}
Setting from flags: iteration= {:level=>:info}
Setting from flags: license=GPL-2.0 {:level=>:info}
Setting from flags: maintainer=Henri Gomez <henri.gomez@gmail.com> {:level=>:info}
Setting from flags: name=openjdk8 {:level=>:info}
Setting from flags: url=https://github.com/hgomez/obuildfactory/ {:level=>:info}
Setting from flags: version=1.8.0-u152-b00 {:level=>:info}
Converting dir to deb {:level=>:info}
No deb_installed_size set, calculating now. {:level=>:info}
Reading template {:path=>"/var/lib/gems/2.3.0/gems/fpm-1.7.0/templates/deb.erb", :level=>:info}
Debian packaging tools generally labels all files in /etc as config files, as mandated by policy, so fpm defaults to this behavior for deb packages. You can disable this default behavior with --deb-no-default-config-files flag {:level=>:warn}
Creating {:path=>"/tmp/package-deb-build-cf3e53cc918d678df4571aa2c9de0ee15217014891b4ea4562ea42a05ebd/control.tar.gz", :from=>"/tmp/package-deb-build-cf3e53cc918d678df4571aa2c9de0ee15217014891b4ea4562ea42a05ebd/control", :level=>:info}
Creating boilerplate changelog file {:level=>:info}
Reading template {:path=>"/var/lib/gems/2.3.0/gems/fpm-1.7.0/templates/deb/changelog.erb", :level=>:info}
Reading template {:path=>"/var/lib/gems/2.3.0/gems/fpm-1.7.0/templates/deb.erb", :level=>:info}
Debian packaging tools generally labels all files in /etc as config files, as mandated by policy, so fpm defaults to this behavior for deb packages. You can disable this default behavior with --deb-no-default-config-files flag {:level=>:warn}
Creating {:path=>"/tmp/package-deb-build-cf3e53cc918d678df4571aa2c9de0ee15217014891b4ea4562ea42a05ebd/control.tar.gz", :from=>"/tmp/package-deb-build-cf3e53cc918d678df4571aa2c9de0ee15217014891b4ea4562ea42a05ebd/control", :level=>:info}
Created package {:path=>"openjdk8_1.8.0-u152-b00_amd64.deb"}
~/openjdkathome/obuildfactory/openjdk8/linux/rpm ~/openjdkathome

You'll then find DEB or RPM files under OBF_DROP_DIR/openjdk8 next to tarballs :

 total 559436
-rw-r--r-- 1 henri henri 165006079 déc.  21 11:23 j2re-image-x86_64-u152-b00-20161221.tar.bz2
-rw-r--r-- 1 henri henri 200628637 déc.  21 11:22 j2sdk-image-x86_64-u152-b00-20161221.tar.bz2
-rw-r--r-- 1 henri henri 207209186 déc.  21 11:23 openjdk8_1.8.0-u152-b00_amd64.deb