OpenJDK引发的血案JavaFx
https://zhuanlan.zhihu.com/p/103765203
案发现场
最近做了一个项目,通过了本地调试,但是部署到服务器上编译失败,出现了以下错误
编译失败,因为缺少javafx.util。
包javafx.util不存在
原因分析
检查代码,因为您在javafx.util中使用了Pair类
那为什么本地编译能通过呢?我看了一下本地jdk版本,打开一个shell窗口进行输入。
java版本
结果如下
看看服务器上jdk的版本。
问题已经浮出水面。服务器上使用OpenJDK。它仍然不同于本地开发环境中使用的jdk。应该说,它是一个不完整的开源版本的JDK,它可能没有JDK那样。具体区别是什么?
JDK与OpenJDK的区别
前世今生
JDK(Java开发工具包)是一个用于Java平台编程的软件开发环境。它包含一个完整的Java运行时环境,即JRE,以及一些Java开发工具(如javac/java/jdb等。)和基本类库。针对不同的使用场景,有三种不同的产品形式:
SE(J2SE),标准版,标准版,是我们常用的一个版本。从JDK 5.0开始,它被重新命名为Java SE。
EE(J2EE),企业版,企业版。使用这个JDK来开发J2EE应用程序,它从JDK 5.0改名为Java EE。
微版ME(J2ME),主要用于移动设备和嵌入式设备上的java应用。从JDK 5.0开始,它被重新命名为Java ME。
这篇文章是关于最常用的标准版。我们常说JDK有两个名字。早期,它叫孙。后来孙被甲骨文收购,改名为甲骨文。这篇文章被统称为甲骨文JDK。
让我们回顾一下甲骨文JDK的版本。
JDK测试版- 1995
JDK 1.0-1996年1996年1月
JDK 1.1-1997年1997年2月
J2SE 1.2-1998 1998年12月
J2SE 2000年5月1日至3日
2002年2月1日至4日
J2SE 5.0-2004年2004年9月
2006年12月6日至12日
Java SE 7-2011年7月(开源主分支再次作为OpenJDK 6之前)
爪哇东南8号(LTS)-2014年3月
爪哇2017年9月9日
Java SE 10(18.3)-2018年3月
爪哇SE 11(18.9 LTS)-2018年9月2018年
Java SE 12(19.3)-2019年3月
不再支持斜体版本。开发JDK7时,OpenJDK已经成为JDK7的骨干开发,2007年为OpenJDK 6开放。此后,Sun JDK7在OpenJDK7的基础上发布,大部分原代码都是一样的,只有少部分被替换。
事实上,Sun从1.5开始就以Java Research License()的形式发布Java源代码,主要供研究人员阅读(License的开源代码是到1.6 Update 23)。将这些OracleJDK源代码的JRL许可形式与对应版本的OpenJDK源代码进行对比,发现除了文件头部的版权说明外,其他代码基本相同,除了字体渲染部分,由Oracle JDK商业实现,而OpenJDK使用开源FreeType。
当然,这里的“相同”是基于两者的共同成分。Oracle JDK中有一些开放JDK中没有的商业闭源功能,比如飞行记录器,Open JDK中也有一些独特的功能。
因为它是开源的,用户可以从
http://hg.openjdk.java.net/jdk8u/jdk8u-dev克隆了源代码,自己编译了OpenJDK。
或者下载源码包,http://jdk7.java.net/source.html,解压后自己编译。
基于这些可重用的源代码,一个非常
多其他版本的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里面是没有的,所以引发了上面的编译错误。解决方式也很简单,主要如下几种做法:
- 不要使用javafx.util这种OpenJDK里面没有的包;
- 本地开发环境直接使用OpenJDK,或者部署时服务器或者容器上使用与本地开发环境版本一致的Oracle JDK,但这会涉及到版权问题;
- 下载javafx-sdk到服务器,编译时将javafx-sdk位置作为--module-path参数传入;l
- 在pom里面显式添加javafx依赖,这样在服务器上用mvn编译时,会把它从maven中央仓库拉到本地打包到你的工程里。
!-- https://mvnrepository.com/artifact/org.openjfx/javafx-base --
dependency
groupIdorg.openjfx/groupId
artifactIdjavafx-base/artifactId
version14-ea+7/version
/dependency
4. 本地编译好,直接用jar包布署。
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/77298.html