How to get the OpenJDK binary tar/zip file?

Since Oracle updated their license for Java 8, a lot of companies started officially maintaining OpenJDK, such as Redhat, Amazon, Alibaba and etc. It’s a good time to switch to OpenJDK.

Unlike Oracle, Redhat doesn’t provide the portable tar/zip of pre-built OpenJDK Linux edition. The zip files are only for Windows. Redhat recommends you to use the offical RPM package to install. Generally, it’s better solution but sometimes it’s very inconvenience, especially when you don’t have the permission but you want to have a quick deployment.

What to do? Docker could help!

  • Pull the image of the CentOS you need. In my case, I used a CentOS 7.7 image.

  • Start the container

  • Install the OpenJDK you need, such as OpenJDK8 or OpenJDK11. For example,

  • Find where the JDK is. In my case, it’s /usr/lib/jvm/java-11-openjdk-11.0.5.10-0.el7_7.x86_64

  • Make a tar file of that folder
  • Copy this tar file out to your local.

By this way, you can get the compatible tar/zip file out. Usually, the dependencies should be fulfilled.

Build OpenJFX 8 in CentOS 6.7 Docker Container

OpenJDK 8 doesn’t include OpenJFX by default. And to make OpenJFX work on old Linux distribution, such as CentOS 6.7, you can not simply follow the official instructions. This article will talk about how to build OpenJFX 8 in CentOS 6.7 docker container.

Start docker container

With docker, it’s extremely easy to get CentOS 6.7 environment.

Instructions

Yum Install Packages


Install GCC/G++ 6, Python 2.7, Ruby 2.4

Reference is https://www.softwarecollections.org/en/scls/rhscl/devtoolset-6/.


Install Gradle, CMake, Ant

Install gradle 4.8 and ant 1.10, update $PATH.


Sync OpenJFX 8 source code

Build without Webkit

Skip the samples and scene-builder build – “vim rt/build.gradle” and comment on the following lines

Start Gradle build.


when the build is done, the javafxsdk-overlay.zip will be generated.


Build with Webkit

With WebKit, the compilation will become extremely slow.

Before doing the steps of “Build without Webkit”, do the following extra steps.

Copy the gradle.properties from the template and enable the Webkit compiling

Enable “COMPILE_WEBKIT“, “BUILD_JAVADOC“, “BUILD_SRC_ZIP“, And specify COMPILE_TARGETS as “linux”

Update buildSrc/linux.gradle a little bit.


Update the symbolic link of /usr/bin/python2

Do the steps of “Build without Webkit“.

 

聊聊ClassLoader in Java World

ClassLoader是Java技术中非常主要的概念,原因是它用来加载Java Class。如果没有Class,也就没有对象;没有对象,就没有之后的一切了。

Java ClassLoader的默认实现是一种双亲结构,即总是尝试让Parent ClassLoader加载类。这样有一些优点,当然也有很大的限制,比如就不利于不同Module对多版本类的加载。更多的细节,在下面我做的PPT里。

还有些新的理解和发现。

  • 自定义的ClassLoader可以把Parent ClassLoader设置为null,如果再把loadClass函数重写,就可以完全屏蔽default classLoader的影响。如OSGi的Bundle ClassLoader的最终的Parent就不是Bootstrap ClassLoader(Bundle ClassLoader的实现还是会去从默认ClassLoader去加载java.*的类)。
  • 程序执行时,ClassLoader的选择。做几个小实验你就会发现,默认的ClassLoader是“加载当前执行函数所在类的ClassLoader”。在OpenJDK的源码中一通Search,就可以找到一些端倪。

在源文件src\interp\engine\interp.c中,有executeJava()函数中,执行ByteCode之前,先准备了MethodBlock的指针,它中间

可以看看GETSTATIC这个指令的实现(此指令会在读取类的静态方法时调用)。可以看到resolveField()方法,并在mb的Class指针传入。idx是Static Field对应Constant Pool里的index。

resolveField中被调用resolveClass函数

resolveClass又回调用findClassFromClass(其实是个Macro),同样传入class指针。看看Macro的定义,就可以很清楚了。

是从ClassBlock结构中找到对应的ClassLoader.

其实记住这个结论就好。这样就可以完全打错传统的ClassLoader的限制,比如OSGi Plugin/Bundle里的所有类就是由OSGi自己的加载器加载的,非常灵活,可以实现非常牛逼的功能!