以前曾经试过在VMware上安装linux,再在linux上编译openjdk8,但是每次都不顺利,例如linux环境,预装依赖软件,openjdk源码的选择等环境都会遇到问题,一旦失败再重新开始挺费时间的,现在用docker就省事多了,镜像和容器的创建和删除都比较简单干净,专心做好Dockerfile就行,下面我们一起来实践一下吧。

本次实战用到的所有文件,已经打包到github上,路径是:https://github.com/zq2599/centos7_build_openjdk8 ,欢迎您来使用(git clone git@github.com:zq2599/centos7_build_openjdk8.git)

本次编译实战的基本步骤如下:

编写的Dockerfile中要做的如下的事情:

  1. 安装依赖的软件;
  2. 把openjdk的源码复制到镜像中;

在编写Dockerfile之前要做三个重要的选择,如下:

  1. linux:我选择了centos7,之前试过ubuntu16.04,但是在configure的时候提示"freetype"没有安装,我按照提示去装了,再次configure的时候继续提示"freetype"没有安装......(此问题现在还没解决,如果您解决过相同问题,请您告诉一下解决方法,谢谢了!)
  2. openjdk源码,这次要编译的是openjdk8,源码的下载地址在这里
  3. Bootstrap JDK:即编译时要用到的JDK,下载了openjdk的源码后,解压开可以看到“README-builds.html”这个文件,里面有对Bootstrap JDK的描述:



    看得出,需要安装jdk7来编译openjdk8的源码;

OK,关键问题都已确认,即将开始Dockerfile制作,不过制作之前还有个小问题需要先想好:本次我打算把制作镜像所需的Dockerfile和依赖文件都放到github上去,这样做的好处有两个:

  1. 读者们从git上clone下来之后直接执行Docker build就能在本地构建镜像;
  2. daocloud.io网站上支持通过执行github目录的方式在线构建镜像,后面我们会实践在daocloud.io上构建镜像并部署到腾讯云或者阿里云服务器上;

上传到github时,除了Dockerfile,还要上传的文件有两个:jdk1.7和openjdk8源码,都超过了100M,如下图:

这就麻烦了,github上传文件的时候,单个文件不能超过100M,否则push的时候会被服务器拒绝,解决这个问题有两个办法:

  1. 构建镜像的时候不要把这两个文件复制到镜像中了,改为在Dockerfile中通过执行wget命令将这两个文件分别下载到镜像中,openjdk的下载路径是http://www.java.net/download/openjdk/jdk8/promoted/b132/openjdk-8-src-b132-03_mar_2014.zip,而jdk1.7的下载路径就难办了,oracle上下载历史版本的时候,是要做登录操作的,这个在Dockerfile中难以实现,找到了一个下载地址https://mirror.its.sfu.ca/mirror/CentOS-Third-Party/NSG/common/x86_64/jdk-7u80-linux-x64.rpm,但是下载速度很慢,最少一个小时以上了,所以wget这种方法看似简单,但下载文件耗时实在太长;
  2. 第二种方法比较简单易用,就是在mac或者linux上先用split命令将文件分割成多个,再上传到github上,在Dockerfile中有对应的命令将分割后的文件恢复成分割前的原文件,具体的分割命令如下:
split -b 50m jdk-7u71-linux-x64.rpm jdkrpm-

这个命令是将jdk-7u71-linux-x64.rpm分割成不超过50m的多个文件,分割后的文件以jdkrpm-作为文件名的前缀,如下图:

opensdk的源码用如下命令分割:

split -b 50m openjdk-8-src-b132-03_mar_2014.zip openjdksrc-

Dockerfile中,从分割文件恢复以上两个原文件的命令为:

cat jdkrpm-* > jdk-7u71-linux-x64.rpm
cat openjdksrc-* > openjdk-8-src-b132-03_mar_2014.zip

以上就是两种处理大文件的方法,本文用的是第二种,即先分割上传到git,在Dockerfile中将已分割文件恢复成原文件再使用。

好了,前期的准备工作已经做完了,现在可以编写Dockerfile文件了,整个文件中要做的事情列出如下:

  1. 安装依赖软件,例如libXtst-devel,libXt-devel等等,这些都是编译前的configure命令要检查的,检查不过无法进行编译;
  2. 把分割后的openjdk源码复制到镜像文件中,再合成,再解压;
  3. 安装jdk7,把分割后的安装文件复制到镜像中合成,然后安装;
  4. 为了方便用户进入容器后快速开始编译,我们做了一个shell脚本start_make.sh,把这个脚本也要复制到镜像中,内容如下:
#!/bin/bash
$WORK_PATH/$OPENJDK_SRC_DIR/configure
echo "start make"
cd $WORK_PATH/$OPENJDK_SRC_DIR
make all ZIP_DEBUGINFO_FILES=0 DISABLE_HOTSPOT_OS_VERSION_CHECK=OK
  1. 清理无用的文件,例如openjdk源码的压缩文件,jdk7的安装文件等;

按照以上步骤,最终写出的Dockerfile文件如下:

# Docker image of compile and build enviroment for openjdk8
# VERSION 0.0.1
# Author: bolingcavalry #基础镜像使用centos7
FROM centos:centos7 #作者
MAINTAINER BolingCavalry <zq2599@gmail.com> #定义工作目录
ENV WORK_PATH /usr/local #定义jdk1.7的文件名
ENV JDK_RPM_FILE jdk-7u71-linux-x64.rpm #定义openJdk源码的文件名
ENV OPENJDK_SRC_ZIP openjdk-8-src-b132-03_mar_2014.zip #定义解压缩后的文件名
ENV OPENJDK_SRC_DIR openjdk #yum更新
RUN yum -y update #安装工具集
RUN yum -y groupinstall "Development Tools" #安装即将用到的软件
RUN yum -y install unzip libXtst-devel libXt-devel libXrender-devel cups-devel freetype-devel alsa-lib-devel which #把分割过的jdk1.7安装文件复制到工作目录
COPY ./jdkrpm-* $WORK_PATH/ #用本地分割过的文件恢复原有的jdk1.7的安装文件
RUN cat $WORK_PATH/jdkrpm-* > $WORK_PATH/$JDK_RPM_FILE #本地安装jdk1.7
RUN yum -y localinstall $WORK_PATH/$JDK_RPM_FILE #把分割过的openJdk8的源码压缩包复制到工作目录
COPY ./openjdksrc-* $WORK_PATH/ #用本地分割过的文件恢复原有的openJdk8的源码压缩包
RUN cat $WORK_PATH/openjdksrc-* > $WORK_PATH/$OPENJDK_SRC_ZIP #解压缩源码
RUN unzip $WORK_PATH/$OPENJDK_SRC_ZIP -d $WORK_PATH #复制启动编译的shell
COPY ./start_make.sh $WORK_PATH/$OPENJDK_SRC_DIR/ #给执行文件增加可执行权限:configure文件
RUN chmod a+x $WORK_PATH/$OPENJDK_SRC_DIR/configure #给执行文件增加可执行权限:启动编译文件
RUN chmod a+x $WORK_PATH/$OPENJDK_SRC_DIR/start_make.sh #删除分割文件
RUN rm $WORK_PATH/jdkrpm-* #删除分割文件
RUN rm $WORK_PATH/openjdksrc-* #删除jdk安装包文件
RUN rm $WORK_PATH/$JDK_RPM_FILE #删除openJdk源码压缩文件
RUN rm $WORK_PATH/$OPENJDK_SRC_ZIP

至此,镜像文件制作所需的材料都已经齐全了,如下图:

现在让我们开始制作镜像吧,打开终端,进入Dockerfile所在目录,执行命令

docker build -t bolingcavalryopenjdk:0.0.1 .

因为要在线安装不少的软件,所以可能耗时会略长,和网络带宽有关,我在住处用家庭网络大概10分钟左右构建成功,执行目录docker images查看镜像,新的镜像文件已经生成了,如下图:

现在启动一个容器试试吧:

docker run --name=jdk001 -idt bolingcavalryopenjdk:0.0.1

容器已经启动,再执行以下命令进入容器:

docker exec -it jdk001 /bin/bash

进去后,直接到/usr/local/openjdk目录下,执行./start_make.sh,开始编译了,整个过程的耗时和当前电脑的硬件配置有关,我用i7处理器的mac pro15大约要用20多分钟,编译结束后会有类似下图的输出:

这时候去/usr/local/openjdk目录下看看,发现多了一个build目录,这里面就是编译好的结果,如下图:

build目录下只有一个linux-x86_64-normal-server-release目录,再进去就能看到jdk目录了,如下图:

进入/usr/local/openjdk/build/linux-x86_64-normal-server-release/jdk/bin目录,会发现里面有java文件,执行./java -version输出如下:

新的jdk信息已经打印出来了,OpenJDK Runtime Enviroment信息已经说明了这是个最新构建的jdk环境。

至此我们的本次实战就结束了,面对如此干净的编译环境和现成的源码,读者您是否有一种改动一番源码的冲动,然后构建一个个性化的属于自己的jdk,如果有兴趣,敬请期待下一次实战,我们一起分析,修改和调试openjdk源码,打造一些个性化的小东东。

欢迎关注我的公众号

在docker上编译openjdk8的更多相关文章

  1. 在Ubuntu 16.04上编译OpenJDK8的源代码

    本文将详细介绍在Ubuntu16.04上对OpenJDK8进行编译. 1.准备编译环境 使用的操作系统为Ubuntu16.04,如果读者没有安装Ubuntu,可以在Windows上使用虚拟机的方式进行 ...

  2. JDK---00Linux上编译openjdk8

    Centos 7 编译自定义jdk8 1. 安装所需的依赖 yum install alsa-lib-devel cups-devel libX* gcc gcc-c++ freetype-devel ...

  3. 试试将.NET7编译为WASM并在Docker上运行

    之前有听到说Docker支持Wasmtime了,刚好.NET7也支持WASM,就带大家来了解一下这个东西,顺便试试它怎么样. 因为WASM(WebAssembly) 一开始是一个给浏览器的技术,比起J ...

  4. JAVA虚拟机学习笔记(一)Windows10下编译OpenJDK8

    转载请注明源地址:http://www.cnblogs.com/lighten/p/5906359.html 1. 编译环境的准备 1.1 JDK源码下载 OpenJDK是JAVA发展史中的一个开源项 ...

  5. JVM-Ubuntu18.04.1下编译OpenJDK8

    近期开始学习JVM,看的是周老师的<深入理解Java虚拟机>,打算先自己编译个JDK来提升对JVM的兴趣.本文分三部分来描述编译OpenJDK的过程,分别是编译前准备工作.构建编译环境.进 ...

  6. 把AspDotNetCoreMvc程序运行在Docker上-part5:使用docker-compose

    在上一part<把AspDotNetCoreMvc程序运行在Docker上-part4:实现负载均衡>中,我们通过几个比较复杂的步骤在docker平台上实现了对网站程序的负载均衡,配置步骤 ...

  7. 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像

    在上一个part<把AspDotNetCoreMvc程序运行在Docker上-part1>,已经将成功将aspdotnetcore程序运行在两个不同的容器中,目前两个容器的内容完全相同,只 ...

  8. Centos7 下编译 Openjdk8

    本文主要介绍如何在 Centos7 下编译 Openjdk8 源码,<深入理解java虚拟机>第二版网上好多 openjdk7 的帖子,编译 jdk8 和 7 还是有些差别的,比如大家经常 ...

  9. 【Step By Step】将Dotnet Core部署到Docker上

    本教程的前提是,你已经在Linux服务器上已经成功的安装了Docker,我会大概介绍在此过程中用到的Docker命令,并不会介绍所有的Docker命令(因为我也不会). 一.在Docker中运行Dot ...

随机推荐

  1. Broadcast 使用详解

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...

  2. 商贸型企业 Java 收货 + 入库 + 生成付款单

    package cn.hybn.erp.modular.system.service.impl; import cn.hybn.erp.core.common.page.LayuiPageFactor ...

  3. kubernetes集群升级的正确姿势

    kubernetes社区非常活跃,每季度都会发布一个release.但是线上集群业务可用性要求较高,场景复杂,任何微小的变更都需要非常小心,此时跟随社区版本进行升级略显吃力.但是为了能够使用到最新的一 ...

  4. word2vec原理分析

    本文摘录整编了一些理论介绍,推导了word2vec中的数学原理,理论部分大量参考<word2vec中的数学原理详解>. 背景 语言模型 在统计自然语言处理中,语言模型指的是计算一个句子的概 ...

  5. CMake入门-02-HelloWorld扩展

    工作环境 系统:macOS Mojave 10.14.6 CMake: Version 3.15.0-rc4 Hello,World! 扩展-同一目录,多个源文件 (1) 新建 hello 目录,创建 ...

  6. Java并发之内存模型(JMM)浅析

    背景 学习Java并发编程,JMM是绕不过的槛.在Java规范里面指出了JMM是一个比较开拓性的尝试,是一种试图定义一个一致的.跨平台的内存模型.JMM的最初目的,就是为了能够支多线程程序设计的,每个 ...

  7. 解决pyinstaller打包可执行文件,存放路径包含中文无法运行的问题

    一.实验环境 1.Windows7x64_SP1 2.anaconda2.5.0 + python2.7(anaconda集成,不需单独安装) 3.pyinstaller3.0 二.问题描述 1.使用 ...

  8. 蔡勒(Zeller)公式及其推导:快速将任意日期转换为星期数

    0. 本文的初衷及蔡勒公式的用处 前一段时间,我在准备北邮计算机考研复试的时候,做了几道与日期计算相关的题目,在这个过程中我接触到了蔡勒公式.先简单的介绍一下蔡勒公式是干什么用的. 我们有时候会遇到这 ...

  9. linux 目录大小 文件个数 基于文件大小排列显示

    显示硬盘占用空间du -hlsblk 查看指定目录大小du -sh /opt查看各个目录大小du -h --max-depth=1 当前目录的全部文件个数(包含子文件夹的文件)ls -lR | gre ...

  10. JD面试 || 移除教室人数

    在昨天参加了东哥的笔试,选择题做的还算可以,但是还有道编程题和关于jdk8的Stream特性难住了.鉴于此用博客总结一下这道编程题,并结合Stream特性来简化代码,熟悉Api. 题目描述 某校在积极 ...