一般使用JDK,就是用OracleJDK和OpenJDK,OracleJDK商用许可证的协议经常变卦;所以,稳妥起见,还是用OpenJDK进行项目开发比较好。

而OpenJDK的众多分支里,我比较喜欢ZuluJDK: www.azul.com/downloads/

ZuluJDK

ZuluJDK是基于OpenJDK开发出来的,使用的协议的: GPL v2 + Classpath exception (GPL v2 + CE)。

使用ZuluJDK,基本上和用OracleJDK没什么区别了;但是不会受到Oracle的协议影响。

关于使用OpenJDK开发Java软件,是否需要遵守 GPLv2而开源,这个还挺有热度讨论的;但是注意这个 Classpath exception ,我认为开发出的软件还是可以不使用GPL协议。

但是有点尴尬,ZuluJDK的项目官网,不是很友好:

国内一些地区经常上不上去(和GitHub一样)。有时候,即使上去了,速度也很慢,甚至一个JDK都下载不下来。

所以,我就想用我香港服务器进行中转,这样还可以给小伙伴们下载JDK。

为了实现ZuluJDK最新版本的下载。准备使用Python解析ZuluJDk的下载地址,之后用wget下载到服务器上,最后使用Nginx进行目录映射。

环境依赖很简单,硬件方面:

  • Linux/macOS:Python使用其wget模块,调用系统wget。
  • Windwos我就不是很清楚,是否有Wget可以调用了。

    Python的模块依赖:

    requests==2.27.1
    wget==3.2
    

    首先观察页面:www.azul.com/downloads/

    发现数据接口:

    将其接口复制,使用paw或者postman进行测试:

    发现这个就是纯JSON对象,而且接收的请求:结构分明。

    那设计就太简单了。

    在Python里用requests库进行模拟请求,请求头:

    URL = "https://www.azul.com/wp-admin/admin-ajax.php?action=bundles&endpoint=community&use_stage=false&include_fields%5B%5D=java_version&include_fields%5B%5D=os&include_fields%5B%5D=javafx&include_fields%5B%5D=latest&include_fields%5B%5D=ext"
    HEADERS = {
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'x-csrf-token': '',
        'x-requested-with': 'XMLHttpRequest',
        'cookie': ''
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'
    

    发送请求并解析为JSON:

    def get_zulu_json():
        response = requests.get(url=URL,
                                headers=HEADERS).json()
        return response
    

    这样就可以把所有ZuluJDK的版本信息获取到了,但是这样有点尴尬,内容过多:

    丢到本地的PAW里测试,有4473项,显然是过去所有的构建版本都在这里了。

    服务器/存储通好大,4473个JDK/JRE……起码有1T的存储空间了。

    所以我们需要过滤。

    处理起来很简单,观察JSON对象的属性,举例:

    "abi": "any", "arch": "arm", "bundle_type": "jdk", "cpu_gen": [ "ext": "zip", "features": [ "jdk" "hw_bitness": "64", "id": 17865, "java_version": [ "javafx": false, "jdk_version": [ "latest": false, "name": "zulu19.0.21-ea-jdk19.0.0-ea.6-macosx_aarch64.zip", "openjdk_build_number": 6, "os": "macos", "release_status": "ea", "sha256_hash": "85493b2ab7bc2cba742856684730ee42a8ee71d3d0a510770a5d0071a2622903", "support_term": "sts", "url": "https://cdn.azul.com/zulu/bin/zulu19.0.21-ea-jdk19.0.0-ea.6-macosx_aarch64.zip", "zulu_version": [

    可以看到,有extlatestname等等参数。一般JDK都是自己配置,操作系统一般也就是Windows、Linux和macOS。

    macOS和Linux的ZuluJDK,通用的肯定是归档文件(tar),Windows的ZuluJDk都是zip文件,且os="windows"

    所以我们过滤两次。

    macOS/Linux

    所以我们对JSON进行过滤:

    def filter_by(zulu_info, latest=None, javafx=None, ext=None, os=None):
        params = locals()
        params.pop('zulu_info')
        for key in params:
            if params[key] is None:
                continue
            if zulu_info.get(key) != params[key]:
                return False
        return True
    download_list=list(filter(lambda x: filter_by(x, javafx=True, ext="tar.gz"), zulu_json))
    
  • zulu_json:上文数据爬取得到的JSON(就是那个4000多对象的◡ ヽ(`Д´)ノ ┻━┻)
  • 丢到本地PyCharm里Debug看看:

    真不错,只有242项了。

    但是这里还有JRE,小伙伴还需要JRE?直接砍了;并且你可以发现,这个JSON对象,数据越前,版本越新。我们就每次只缓冲下载最新版本的吧:

    # 用于记数
    temp_list = {}
    for item in filtered_list:
        # 正则判断是否是JDK
        if re.search(r"jdk", item['name']) is None:
            # 不是JDK,直接跳过循环
            continue
        # 查看JDK版本(大版本,如:JDK11、JDK17等)
        jdk_version_code = str(item['jdk_version'][0])
        # 拼接为系统+JDK版本形式
        OS_version = jdk_version_code + item['name'].split("-")[-1]
        # 如果对象存在,直接跳出循环
        if OS_version in temp_list.keys():
            continue
        else:
            temp_list[OS_version] = 1,
    

    这样,就可以保证,每个系统的每个大版本,只下载一次,242项变20项以内(只有macOS和Linux)。

    Windows

    Windows的过滤和下载macOS和Linux的方法一样了:

    download_list=list(filter(lambda x: filter_by(x, javafx=True, ext="zip",os="windows"), zulu_json))
    

    一共有90+,和刚刚Linux方法一样,过滤掉JRE,只去最新版本,应该会更少。

    下载JDK

    最后,我们就是下载了。这里使用wget对数据进行下载;Python的wget模块:pypi.org/project/wge…

    这个可不是GNU的wget工具,是用来Python里调用wget进行下载的。

    安装wget模块:

    pip3 install wget
    

    定义一个下载目录:

    def has_dir(path):
        if not os.path.exists(path):
            os.makedirs(path)
    

    之后不全过滤时候的代码:

    def download_by_list(filtered_list):
        temp_list = {}
        for item in filtered_list:
            if re.search(r"jdk", item['name']) is None:
                continue
            jdk_version_code = str(item['jdk_version'][0])
            OS_version = jdk_version_code + item['name'].split("-")[-1]
            if OS_version in temp_list.keys():
                continue
            else:
                temp_list[OS_version] = 1,
            # 设置wget下载目录
            save_path = "ZuluJDK_Mirror/" + jdk_version_code + "/"
            # 判断目录是否存在
            has_dir(save_path)
            print("开始下载:" + item['name'])
            wget.download(item['url'], out=save_path + item['name'])
            print("\n")
            # 线程休眠
            time.sleep(20)
    

    最后,我们编写的Python脚本:

    使用Python命令运行:

    最后下载下来的文件:

    使用Nginx做个目录映射:

    当然,我们可以使用Cron定期缓冲最新版本的ZuluJDK,这里就不演示了。

    最后,我们就可以把Nginx目录映射的地址发给想下载ZuluJDK的小伙伴了。

    另外…… 突然发现:我直接解析了ZuluJDK的直链,用Nginx进行反代……似乎更方便;还不用占服务器空间!!!

    不过,还是这样好点,确保资源持久化~~~

    分类:
    后端
    标签: