• 一场因OpenJDK引发的血案 之JavaFx


    https://zhuanlan.zhihu.com/p/103765203

    案发现场

    最近做了个项目,本地调试通过了,可在服务器上部署时却编译失败,报错如下

    编译失败的原因是缺少javafx.util。

    package javafx.util does not exist

    原因分析

    查看代码,是因为使用了javafx.util中的Pair类

    那为什么本地可以编译通过了?我本看下本地jdk版本,打开一个shell窗口输入

    java --version

    结果如下

    再看看服务器上jdk的版本

    问题浮出水面了,服务器上用的是OpenJDK。它跟本地开发环境所用的JDK还是有区别的,应该说它是一个不完整的jdk的开源版本,JDK有的东西它不一定有。具体区别体现在哪里了?

    JDK与OpenJDK的区别

    前世今生

    JDK(Java Development Kit)是Java平台编程中使用的软件开发环境。它包含一个完整的Java运行时环境,即JRE,以及一些Java开发工具(如javac/java/jdb等)与基础类库等。针对不同使用场景,其有三个不同的产品形态:

    • SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。
    • EE(J2EE),enterprise edition,企业版,使用这种JDK开发J2EE应用程序,从JDK 5.0开始,改名为Java EE。
    • ME(J2ME),micro edition,主要用于移动设备、嵌入式设备上的java应用程序,从JDK 5.0开始,改名为Java ME。

    本文讲的是最常用的标准版。我们常说的JDK有两种叫法,早期叫做Sun JDK,后来Sun被Oracle收购了,又改叫Oracle JDK,本文统称Oracle JDK。

    我们回顾下Oracle JDK的版本

    • JDK Beta - 1995
    • JDK 1.0 - 1996年1月
    • JDK 1.1 - 1997年2月
    • J2SE 1.2 - 1998年12月
    • J2SE 1.3 - 2000年5月
    • J2SE 1.4 - 2002年2月
    • J2SE 5.0 - 2004年9月
    • Java SE 6 - 2006年12月
    • Java SE 7 - 2011年7月(再次之前先将主分支作为OpenJDK 6开源)
    • Java SE 8(LTS) - 2014年3月
    • Java SE 9 - 2017年9月
    • Java SE 10(18.3) - 2018年3月
    • Java SE 11(18.9 LTS) - 2018年9月
    • Java SE 12(19.3) - 2019年3月

    其中斜体版本不再支持。在开发JDK7的时候,OpenJDK已经成为JDK7的主干开发,并在2007年开源,是为OpenJDK 6。此后Sun JDK7是在OpenJDK7的基础上发布的,其大部分原始码都相同,只有少部分原始码被替换掉。

    其实Sun自JDK 1.5之后就开始以Java Research License(JRL)的形式公布过Java源码,主要用于研究人员阅读(JRL许可证的开放源码至JDK 1.6 Update 23为止)。把这些JRL许可证形式的OracleJDK源码和对应版本的OpenJDK源码进行比较,发现除了文件头的版权注释之外,其余代码基本上都是相同的,只有字体渲染部分存在一点差异,Oracle JDK采用了商业实现,而OpenJDK使用的是开源的FreeType。

    当然,这里的“相同”是建立在两者共有的组件基础上的,Oracle JDK中还会存在一些Open JDK没有的、商用闭源的功能,例如Flight Recorder,OpenJDK中也有少量独有功能。

    由于是源码开放,用户可以从

    将源代码clone下来自己编译OpenJDK

    或者下载源码包,,解压后自己编译。

    并且基于这些可复用的源码,诞生了很多其他版本的JDK,例如IcedTea、UltraViolet都是从OpenJDK源码衍生出的发行版,一些大公司也有自己的版本如Amazon Corretto,alijdk等。

    自此OpenJDK成为由Oracle,OpenJDK和Java社区开发共同维护的单独的一个项目,目前主要版本如下

    OpenJDK 6项目 - 基于JDK 7,但经过修改后提供了Java 6的开源版本
    OpenJDK 7项目 - 2011年7月28日
    OpenJDK 7u项目 - 该项目开发Java Development Kit 7的更新
    OpenJDK 8项目 - 2014年3月18日
    OpenJDK 8u项目 - 该项目开发Java Development Kit 8的更新
    OpenJDK 9项目 - 2017年9月21日
    JDK项目于2018年3月10日至20日发布
    JDK项目于2018年9月11日至25日发布
    JDK项目发布12 - 稳定阶段

    可以说OpenJDK是自jdk7版以来Java标准版的官方参考实现。它和Oracle JDK的主要区别如下:

    OpenJDK不包含Deployment(部署)功能

    部署的功能包括:Browser Plugin、Java Web Start、以及Java控制面板,这些功能在OpenJDK中是找不到的。

    OpenJDK源代码不完整

    这个很容易想到,在采用GPL协议的OpenJDK中,SUN JDK的一部分源代码因为产权的问题无法开放给OpenJDK使用,其中最主要的部份就是JMX中的可选元件SNMP部份的代码。

    部分源代码用开源代码替换

    出于产权的问题,很多产权不是SUN的源代码被替换成一些功能相同的开源代码,比如前面跳到的说字体渲染部分的实现在OpenJDK中使用Free Type代替。

    OpenJDK只包含最精简的JDK

    OpenJDK不包含其他的软件包,比如Rhino Java DB JAXP……,并且可以分离的软件包也都是尽量的分离,但是这些大多是自由软件,你可以自己下载安装。包括这里遇到的javafx,也可以自己下载安装到openJDK的类库中。

    功能上

    应该说,两者之间超过99%的功能都是相同的,细微的区别在于Oracle JDK具有Flight Recorder,Java Mission Control,Application Class-Data Sharing 功能以及更多的垃圾收集选项和更好的渲染器,而OpenJDK具有Font Renderer功能。




    许可证

    Oracle JDK:GPL(通用公共许可证)

    OpenJDK:GNU,GPL

    在没有商业许可的情况下,在2019年1月之后发布的Oracle Java SE 8的公开更新将无法用于商业用途。但是,OpenJDK是完全开源的,可以自由使用。正因如此,一般服务器上用的都是OpenJDK。

    稳定性

    Oracle JDK构建过程是基于OpenJDK的,所以他们之间并没有技术差别。只是OpenJDK由于版本发布比较频繁,可能会遇到不稳定的问题。根据社区反馈,也有一些OpenJDK用户遇到了性能问题。而Oracle JDK作为商业软件,在稳定性方面要好很多,或许OpenJDK就是给Oracle JDK踩坑用的吧,哈哈。

    解决办法

    这里的javafx.util包在jdk 1.8的类库里面有,但在OpenJDK 8里面是没有的,所以引发了上面的编译错误。解决方式也很简单,主要如下几种做法:

    1. 不要使用javafx.util这种OpenJDK里面没有的包;
    2. 本地开发环境直接使用OpenJDK,或者部署时服务器或者容器上使用与本地开发环境版本一致的Oracle JDK,但这会涉及到版权问题;
    3. 下载javafx-sdk到服务器,编译时将javafx-sdk位置作为--module-path参数传入;l
    4. 在pom里面显式添加javafx依赖,这样在服务器上用mvn编译时,会把它从maven中央仓库拉到本地打包到你的工程里。
    <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-base -->
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-base</artifactId>
        <version>14-ea+7</version>
    </dependency>

    4. 本地编译好,直接用jar包布署。

  • 相关阅读:
    解决下载文件过大而不能下载的问题.... 分类: tomcat 20091106 23:24 404人阅读 评论(0) 收藏
    javascript 的参数有长度限制吗?一个细节引起的误区 分类: 网页编程【html、js】 20091110 08:34 1673人阅读 评论(0) 收藏
    cookie的生死之道 分类: 网页编程【html、js】 20091114 03:51 364人阅读 评论(0) 收藏
    java调用存储过程 分类: java 20091112 08:46 479人阅读 评论(1) 收藏
    Boolean.getBoolean(String name)............. 分类: java 20091112 05:42 1093人阅读 评论(1) 收藏
    greatest()函数 和 least()函数 分类: 数据库 20091108 09:21 810人阅读 评论(0) 收藏
    git push u origin master和git push <远程主机名> <本地分支名>:<远程分支名>作用
    Windows下安装Memcached
    关系型数据库性能优化总结
    GridView导出为Excel乱码解决方案
  • 原文地址:https://www.cnblogs.com/exmyth/p/15528281.html
Copyright © 2020-2023  润新知