400-888-0545
有创意,就创造,让信息化建设更便捷更高效
O2OA是基于JavaEE分布式架构的全平台,全终端,国产化开源低代码开发平台。平台拥有5个核心系统以及多个内置应用,能够让开发者根据客户需求按需定制、零代码快速实现复杂业务管理,和现有组织架构、基础数据、权限体系形成一体化业务建模。
开发方式及特点
1. 平台全功能源码公开(包括移动端),官方承诺无任何功能和人数限制。
2. 可视化开发,流程、表单编辑所见即所得,界面样式支持灵活定制,可集成Vue,React以及Angular。
3. Nashorn引擎,支持直接使用JavaScript完成服务代码编写并且发布使用。
4. 支持第三方以Restful服务方式驱动和管理流程,支持平台与第三方服务的数据交互。
5. 支持私有化部署、内网部署,支持传输加密,数据更安全。
6. 提供原生的IOS/Android应用, 并且支持WeLink、钉钉和企业微信集成。
How to Start

windows

1.下载o2server. yyyyMMddHHmmss_ windows.zip程序包.
2.解压下载后的压缩包到任意目录
3.确认开通服务器的80、20020、20030端口
4.打开o2server文件夹,选择start_ windows.bat双击打开
5.启动服务,等待相关服务自动完成.
6.自动完成后打开浏览器访问http://127.0.0.1
7.输入用户名xadmin密码o2登陆系统

linux

1.下载o2server. yyyyMMddHHmmss_linux.zip程序包.
2.确认开通服务器的80、20020、20030端口
3."unzip o2server. syyyMMddHHmmss linux.zip" 解压程序包.
4."cd o2server. yyyMMddHHmmss_ linux" 进入解压目录
5."cd o2server"进入程序目录.
6."./start. linux.sh" 回车启动服务器控制台.
7.启动服务,等待相关服务自动完成.
8.自动完成后打开浏览器访问http://127.0.0.1
9.输入用户名xadmin密码o2登陆系统

Configure The Compilation Environment

JVM 下载

安装NodeJS

1. 访问nodejs的官方网站的downdolad,网址:https://nodejs.org/en/download/,获取Linux Binaries (x64)安装包下载链接:

wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-x64.tar.xz

2. 解压安装:

# yum search xz # yum install xz.i386
# xz -d node-v10.15.0-linux-x64.tar.xz
# tar -xf node-v10.15.0-linux-x64.tar
# mv node-v10.15.0-linux-x64 node-v10.15.0

3. 配置nodejs(略)

安装 Java8 及配置Java环境

安装 apache-maven-3.6.0 及配置maven环境

wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo

Source Code Compilation

1、打开命令提示工具,cd到o2oa/o2server目录cd /usr/o2oa/o2server
2、执行命令进行编译: mvn install,开始进行源码编译mvn install

关于编译错误

o2oa/o2server/target目录下会有打包好的zip包,将此zip包Copy到其他目录解压(避免目录层级太深造成启动异常),
服务器部署和后动相关的教程文档, 请移步系列教程: https://my.oschina.net/u/3931542/blog/2209110

程序人生
5/10 第1
《GB∕T 33190-2016 电子文件存储与交换格式 版式文件》OFD标准学习及应用
OFD标准介绍什么是OFDOFD(Open Fixed-Layout Document) 是电子文件管理的基础标准之一,由于其固定版式呈现的特点,各类文档排版后的固化结果都可使用本标准来承载 ;同时对于各行业管理中有关元数据、语义、数字签名等要求,本标准也提供相应的可扩展机制予以支持。OFD作为基础标准在版式文档范畴内反映了行业管理要求,提供了足够的扩展性,与行业应用中的标准规范是并行的,各行业规范只在版式文档存储格式方面引用本标准。OFD版式文件具有以下特点:(1)采用XML技术描述文本数据,采用“容器+文档”的方式描述和存储数据;(2)真实地保持原有文档中文字、图表、公式、色彩等版式信息,且这种特性不随平台变化而改变;(3)采用二维向量图像模型,可以描述包括文字、图形、图像等经过精密排版的页面像素;(4)国家层级的自主版式格式,实现了文档的原始内容和批注附加内容的分离保存 OFD学习资源可在国家标准全文公开系统预览《GB∕T 33190-2016 电子文件存储与交换格式 版式文件》标准内容;OFD阅读器厂商:北京数科网维,航天福昕软件OFD格式转换:北京数科网维文档转换预览,福昕OFD版式办公套件安装完成后可通过虚拟打印机转换为OFD格式,永中DCS  在OFD文件中添加档案章  准备工作:档案章图片(生成细节略)、OFD文件、Visual Studio IDE OFD文件解压可将文件后缀名改为zip再解压以查看OFD文件的层次结构。实际编码中需要引入System.IO.Compression.ZipFile包。   文件说明OFD.xml文件主人口文件,一个包内存在且只存在一个OFD.xml 文件,此文件名不应修改Doc_0/Document.xml文档的根节点Doc_0/DocumentRes.xml文档自身资源索引Doc_0/PublicRes.xml文档公共资源索引Doc_0/Pages/Page_0/Cotent.xml文档第0 页的内容描述Doc_0/Res/seal.png文档资源文件 ZipFile.ExtractToDirectory(ofd文件路径, 解压目录); 读取相关数据注意:OFD标准中XML文档使用的命名空间为http://www.ofdspec.org/201 6,其标识应为ofd;应在包内各XML文档的根节点中声明defaults:ofd。元素节点应使用命名空间标识,元素属性不使用命名空间。   有些厂商转换的OFD文件命名空间为http://www.ofdspec.org或其它,因此需要根据文件指定的命名空间来读取和写入数据。 IDXML文件XPath数据1OFD.xmlofd:OFD/ofd:DocBody/ofd:DocRoot主入口文件路径2Document.xmlofd:Document/ofd:CommonData/ofd:MaxUnitID文档全局自增ID3Document.xmlofd:Document/ofd:CommonData/ofd:DocumentRes资源文件路径4Document.xmlofd:Document/ofd:Pages/ofd:Page[1]首页路径5DocumentRes.xmlofd:Res/ofd:MultiMedias/ofd:MultiMedia/ofd:MediaFile[text()='seal.png']档案章图片名称6DocumentRes.xmlofd:Res/ofd:MultiMedias/ofd:MultiMedia/ofd:MediaFile[text()='seal.png']/..档案章图片资源ID7Content.xmlofd:Page/ofd:Area/ofd:PhysicalBox页面尺寸信息 写入数据(1)     将六格档案章图片复制到解压目录相对路径Doc_N/Res下,Doc_N由数据1决定;(2)     DocumentRes.xml文件ofd:Res/ofd:MultiMedias路径下创建子元素MultiMedia,DocumentRes.xml路径由数据3决定,并自增数据2写入ID属性;(3)     在上一步MultiMedia节点创建子元素MediaFile;(4)     Content.xml文件ofd:Page/ofd:Content/ofd:Layer路径下创建子元素ImageObject,Content.xml路径由数据4决定,并自增数据2写入ID属性;其中Boundary、CTM由数据7计算得出,需将图片像素先转换为毫米再进行计算,ResourceID为第(2)步的自增ID;(5)     更新Document.xml文件ofd:Document/ofd:CommonData/ofd:MaxUnitID值为数据2;(6)     保存以上所有修改 OFD文件打包打包并删除临时解压文件ZipFile.CreateFromDirectory(解压路径, ofd文件路径);Directory.Delete(解压路径, true); sealopenssllayervisual studio本文转载自:https://www.cnblogs.com/WalkingDead/p/11679072.html
27
2020-10
各种主流软件开源协议解释说明
世界上的开源许可证,大概有上百种。反正笔者是搞不懂他们之间的区别。目前最常见、最流行的六种开源协议:GPL、BSD、MIT、Mozilla、Apache和LGPL,看起来还是很复杂。找到中文说明:http://www.gnu.org/licenses/license-list.html原来看懂开源协议也挺难的,开始怀疑自己的理解能力。图片引用阮一峰的博客:  https://www.ruanyifeng.com/blog/2011/05/how_to_choose_free_software_licenses.html据说此图出自乌克兰程序员Paul Bagwell不花钱,还能拿来赚钱,拿来基本随便用,能闭源-区别在于广告和版权说明一:Apache Licence-随便改,广告也无所谓,版权上有我名字Apache Licence :Apache License, Version 2.0、Apache License, Version 1.1、Apache License, Version 1.0)Apache Licence是著名的非盈利开源组织Apache采用的协议。鼓励代码共享和尊重原作者的著作权,同样允许代码修改,再发布(作为开源或商业软件)二:MIT(MIT)-随便改,不能写我的名字打广告,版权无所谓MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制.也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的。三:BSD开源协议(original BSD license、FreeBSD license、Original BSD license)-随便改,什么都无所谓BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。不能“免费”拿来赚钱四:MPL(Mozilla Public License)-您的修改归开源软件的发起者,这是奉献精神MPL协议允许免费重发布、免费修改,但要求修改后的代码版权归软件的发起者 。这种授权维护了商业软件的利益,它要求基于这种软件的修改无偿贡献版权给该软件。五:GPL(GNU General Public License)-我开源,你就得开源我们很熟悉的Linux 就是采用了GPL 。GPL 协议和BSD, Apache Licence 等鼓励代码重用的许可很不一样。GPL不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux ,包括商业公司的linux 和linux 上各种各样的由个人,组织,以及商业软件公司开发的免费软件了。GPL 协议的主要内容是只要在一个软件中使用(” 使用” 指类库引用,修改后的代码或者衍生代码)GPL 协议的产品,则该软件产品必须也采用GPL 协议,既必须也是开源和免费。这就是所谓的” 传染性”。GPL 协议的产品作为一个单独的产品使用没有任何问题,还可以享受免费的优势。由于GPL 严格要求使用了GPL 类库的软件产品必须使用GPL 协议,对于使用GPL 协议的开源代码,商业软件或者对代码有保密要求的部门就不适合集成/ 采用作为类库和二次开发的基础。六:LGPL(GNU Lesser General Public License)-可以有部分代码不开源,有点赚头LGPL 协议的开源 代码很适合作为第三方类库被商业软件引用LGPL 是GPL 的一个为主要为类库使用设计的开源协议。和GPL 要求任何使用/ 修改/ 衍生之GPL 类库的的软件必须采用GPL 协议不同。LGPL 允许商业软件通过类库引用(link) 方式使用LGPL 类库而不需要开源商业软件的代码。这使得采用LGPL 协议的开源代码可以被商业软件作为类库引用并 发布和销售。但是如果修改LGPL 协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL 协议。因此LGPL 协议的开源 代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL 协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。O2OA 使用的开源协议 AGPL(Affero General Public License)协议说明https://www.gnu.org/licenses/why-affero-gpl.html说人话:1.APGL协议,您可以随意修改、自用,但是不能用来商用。2.APGL协议,您可以自用,但是不能再互联网上搭建服务,提供给网友使用。例如:你不能用o2oa搭建一个多租户平台在互联网上进行用户注册售卖,这样会有法律风险。引用自开源中国购买o2oa商用许可授权后,您相当于得到了一套商业软件的源码和使用权,不受开源协议的限制。
23
2020-09
导致MySQL索引失效的几种常见写法
最近一直忙着处理原来老项目遗留的一些SQL优化问题,由于当初表的设计以及字段设计的问题,随着业务的增长,出现了大量的慢SQL,导致MySQL的CPU资源飙升,基于此,给大家简单分享下这些比较使用的易于学习和使用的经验。这次的话简单说下如何防止你的索引失效。再说之前我先根据我最近的经验说下我对索引的看法,我觉得并不是所以的表都需要去建立索引,对于一些业务数据,可能量比较大了,查询数据已经有了一点压力,那么最简单、快速的办法就是建立合适的索引,但是有些业务可能表里就没多少数据,或者表的使用频率非常不高的情况下是没必要必须要去做索引的。就像我们有些表,2年了可能就10来条数据,有索引和没索引性能方面差不多多少。索引只是我们优化业务的一种方式,千万为了为了建索引而去建索引。下面是我此次测试使用的一张表结构以及一些测试数据CREATE TABLE `user` ( `id` int(5) unsigned NOT NULL AUTO_INCREMENT, `create_time` datetime NOT NULL, `name` varchar(5) NOT NULL, `age` tinyint(2) unsigned zerofill NOT NULL, `sex` char(1) NOT NULL, `mobile` char(12) NOT NULL DEFAULT '', `address` char(120) DEFAULT NULL, `height` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_createtime` (`create_time`) USING BTREE, KEY `idx_name_age_sex` (`name`,`sex`,`age`) USING BTREE, KEY `idx_ height` (`height`) USING BTREE, KEY `idx_address` (`address`) USING BTREE, KEY `idx_age` (`age`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=261 DEFAULT CHARSET=utf8;INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (1, '2019-09-02 10:17:47', '冰峰', 22, '男', '1', '陕西省咸阳市彬县', '175'); INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (2, '2020-09-02 10:17:47', '松子', 13, '女', '1', NULL, '180'); INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (3, '2020-09-02 10:17:48', '蚕豆', 20, '女', '1', NULL, '180'); INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (4, '2020-09-02 10:17:47', '冰峰', 20, '男', '17765010977', '陕西省西安市', '155'); INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (255, '2020-09-02 10:17:47', '竹笋', 22, '男', '我测试下可以储存几个中文', NULL, '180'); INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (256, '2020-09-03 10:17:47', '冰峰', 21, '女', '', NULL, '167'); INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (257, '2020-09-02 10:17:47', '小红', 20, '', '', NULL, '180'); INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (258, '2020-09-02 10:17:47', '小鹏', 20, '', '', NULL, '188'); INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (259, '2020-09-02 10:17:47', '张三', 20, '', '', NULL, '180'); INSERT INTO `bingfeng`.`user`(`id`, `create_time`, `name`, `age`, `sex`, `mobile`, `address`, `height`) VALUES (260, '2020-09-02 10:17:47', '李四', 22, '', '', NULL, '165');单个索引1、使用!= 或者 <> 导致索引失效SELECT * FROM `user` WHERE `name` != '冰峰';我们给name字段建立了索引,但是如果!= 或者 <> 这种都会导致索引失效,进行全表扫描,所以如果数据量大的话,谨慎使用可以通过分析SQL看到,type类型是ALL,扫描了10行数据,进行了全表扫描。<>也是同样的结果。2、类型不一致导致的索引失效在说这个之前,一定要说一下设计表字段的时候,千万、一定、必须要保持字段类型的一致性,啥意思?比如user表的id是int自增,到了用户的账户表user_id这个字段,一定、必须也是int类型,千万不要写成varchar、char什么的骚操作。SELECT * FROM `user` WHERE height= 175;这个SQL诸位一定要看清楚,height表字段类型是varchar,但是我查询的时候使用了数字类型,因为这个中间存在一个隐式的类型转换,所以就会导致索引失效,进行全表扫描。现在明白我为啥说设计字段的时候一定要保持类型的一致性了不,如果你不保证一致性,一个int一个varchar,在进行多表联合查询(eg: 1 = '1')必然走不了索引。遇到这样的表,里面有几千万数据,改又不能改,那种痛可能你们暂时还体会。少年们,切记,切记。3、函数导致的索引失效SELECT * FROM `user` WHERE DATE(create_time) = '2020-09-03';如果你的索引字段使用了索引,对不起,他是真的不走索引的。4、运算符导致的索引失效SELECT * FROM `user` WHERE age - 1 = 20;如果你对列进行了(+,-,*,/,!), 那么都将不会走索引。5、OR引起的索引失效SELECT * FROM `user` WHERE `name` = '张三' OR height = '175';OR导致索引是在特定情况下的,并不是所有的OR都是使索引失效,如果OR连接的是同一个字段,那么索引不会失效,反之索引失效。6、模糊搜索导致的索引失效SELECT * FROM `user` WHERE `name` LIKE '%冰';这个我相信大家都明白,模糊搜索如果你前缀也进行模糊搜索,那么不会走索引。7、NOT IN、NOT EXISTS导致索引失效SELECT s.* FROM `user` s WHERE NOT EXISTS (SELECT * FROM `user` u WHERE u.name = s.`name` AND u.`name` = '冰峰')SELECT * FROM `user` WHERE `name` NOT IN ('冰峰');这两种用法,也将使索引失效。但是NOT IN 还是走索引的,千万不要误解为 IN 全部是不走索引的。我之前就有误解(丢人了...)。8、IS NULL不走索引,IS NOT NULL走索引SELECT * FROM `user` WHERE address IS NULL不走索引。SELECT * FROM `user` WHERE address IS NOT NULL;走索引。根据这个情况,建议大家这设计字段的时候,如果没有必要的要求必须为NULL,那么最好给个默认值空字符串,这可以解决很多后续的麻烦(有深刻的体验<体验=教训>)。复合索引1、最左匹配原则EXPLAIN SELECT * FROM `user` WHERE sex = '男';EXPLAIN SELECT * FROM `user` WHERE name = '冰峰' AND sex = '男';测试之前,删除其他的单列索引。啥叫最左匹配原则,就是对于符合索引来说,它的一个索引的顺序是从左往右依次进行比较的,像第二个查询语句,name走索引,接下来回去找age,结果条件中没有age那么后面的sex也将不走索引。注意:SELECT * FROM `user` WHERE sex = '男' AND age = 22 AND `name` = '冰峰';可能有些搬砖工可能跟我最开始有个误解,我们的索引顺序明明是name、sex、age,你现在的查询顺序是sex、age、name,这肯定不走索引啊,你要是自己没测试过,也有这种不成熟的想法,那跟我一样还是太年轻了,它其实跟顺序是没有任何关系的,因为mysql的底层会帮我们做一个优化,它会把你的SQL优化为它认为一个效率最高的样子进行执行。所以千万不要有这种误解。2、如果使用了!=会导致后面的索引全部失效SELECT * FROM `user` WHERE sex = '男' AND `name` != '冰峰' AND age = 22;我们在name字段使用了 != ,由于name字段是最左边的一个字段,根据最左匹配原则,如果name不走索引,后面的字段也将不走索引。关于符合索引导致索引失效的情况能说的目前就这两种,其实我觉得对于符合索引来说,重要的是如何建立高效的索引,千万不能说我用到那个字段我就去建立一个单独的索引,不是就可以全局用了嘛。这样是可以,但是这样并没有符合索引高效,所以为了成为高级的搬砖工,我们还是要继续学习,如何创建高效的索引。
23
2020-09
10 月 1 日起,GitHub 中的 master 将默认更改为 main
GitHub 官方表示,从今年 10 月 1 日起,在该平台上创建的所有新的源代码仓库将默认被命名为 "main",而不是原先的"master"。值得注意的是,现有的存储库不会受到此更改影响。早在今年 6 月份,受美国大规模的 “Black Lives Matter”运动影响,为了安抚愈演愈烈的民众情绪,GitHub 就宣布将替换掉 master 等术语,以避免联想奴隶制。现如今,在外界一些声音的催促下,这一举措则终于要正式落地了。除 GitHub 外,为了避免带有所谓的“种族歧视色彩”,许多科技巨头或知名软件也都调整了自己的业务和产品,以平息社会舆论。包括有:MySQL 宣布删除 master、黑名单白名单等术语;Linus Torvalds 通过了 Linux 中避免 master/slave 等术语的提案;还有 Twitter 、GitHub、微软、LinkedIn、Ansible、Splunk、OpenZFS、OpenSSL、JP Morgan、 Android 移动操作系统、Go 编程语言、PHPUnit 和 Curl 等宣布要对此类术语进行删除或更改。同时,IBM、亚马逊、微软也都接连调整面部识别平台业务,以防加深歧视或遭受指责。且最初在 Git 中写下“master”一词的开发者 Petr Baudis 也于 6 月份在社交网站上表明立场称,自己当年不该使用“master”这个可能给别人造成伤害的词语。并表示,他曾多次希望可以将“master”改成“main”(和“upstream”)。不过直到现在,才由 GitHub 开始主导替换工作。而对于为何选择“main”而不是其他替换词汇,Github 方面给出的解释为,main 是他们在平台上看到的最受欢迎的 master 替代品。并且 main 这个词汇很短,可以帮助用户形成良好的肌肉记忆;在很多种语言中翻译起来也都很容易。目前,该平台已将 main 用于新创建的仓库和正在迁移的仓库,例如 dependabot-core。不过,Github 也指出,对于现有的仓库来说,重命名默认分支的举措无可避免地会造成一些麻烦,譬如必须编辑拉请求的设置和修改安全策略等。此外,Github 还透露,截至今年年底,他们将使现有存储库无缝重命名其默认分支。当用户重命名分支机构时,他们将重新定位打开的 PR 和草稿版本、移动分支机构保护策略等,且所有的这些都将自动完成。事实上,计算机术语政治正确性早已不是新鲜话题。2004 年,“master/slave”曾被全球语言检测机构评为年度最不政治正确的十大词汇之一,时任主席称这是政治渗透到计算机技术控制中的表现。2008 年,开源软件 Drupal 在社区发布消息,高调站队,将“master/slave”重命名为“client/server”。2018年,IETF 也在草案当中指出,要求开源软件更改“master/slave”和“blacklist/whitelist”两项表述。然而在一些开发者呼吁一些开源软件厂商修改源码,清除此类词汇的同时,也有很多人持反对意见。其中最突出的两个理由则是:计算机源码中的“master、blacklist”等词语并不包含歧视情绪;和更改的成本不低。 可以理解的是,倡议者们想表达的是,并不是不能使用“黑”这个词,而是希望不要把“黑”作为“白”的对立面,表达“不好”、“坏”、“需要被限制”等负面意思。同理,当“master、slave”出现在源码中,并且表达的“主-从”关系,这会让一些人联想到奴隶制。但是值得思考的是,在计算机源码领域中,“master/slave”和“blacklist/whitelist”之类的技术用语有错吗?一味的“一刀切”的话,会不会导致所谓的矫枉过正呢?转载自:https://www.oschina.net/news/118751/github-to-replace-master-with-main
23
2020-09
Oracle JDK 15安装及新特性介绍
JDK 15已经于2020年9月15日如期发布。本文介绍JDK 15新特性。发布版本说明根据发布的规划,这次发布的 JDK 15 将是一个短期的过度版,只会被 Oracle 支持(维护)6 个月,直到明年 3 月的 JDK 16 发布此版本将停止维护。而 Oracle 下一个长期支持版(LTS 版)会在明年的 9 月份候发布(Java 17),LTS 版每 3 年发布一个,上一次长期支持版是 18 年 9 月发布的 JDK 11。 下图展示了各个版本的发布历史。安装包下载主要分为OpenJDK版本和Oracle版本,下载地址如下:OpenJDK版本:https://jdk.java.net/15/Oracle版本:http://www.oracle.com/technetwork/java/javase/downloads/index.html上述版本,如果是个人学习用途,则差异不大。但如果是用于商业用途,则需要仔细看好相关的授权。Oracle JDK根据二进制代码许可协议获得许可,而OpenJDK根据GPL v2许可获得许可。安装、验证本例子以OpenJDK版本为例。解压安装包openjdk-15_windows-x64_bin.zip到任意位置。设置系统环境变量“JAVA_HOME”,如下图所示。在用户变量“Path”中,增加“%JAVA_HOME%\bin”。安装完成后,执行下面命令进行验证:>java -version openjdk version "15" 2020-09-15 OpenJDK Runtime Environment (build 15+36-1562) OpenJDK 64-Bit Server VM (build 15+36-1562, mixed mode, sharing)更多有关Java的基本知识,可以参阅《Java核心编程》这本书,描述的非常详细。JDK 15 新特性说明JDK 15 为用户提供了14项主要的增强/更改,包括一个孵化器模块,三个预览功能,两个不推荐使用的功能以及两个删除功能。1. EdDSA 数字签名算法新加入 Edwards-Curve 数字签名算法(EdDSA)实现加密签名。在许多其它加密库(如 OpenSSL 和 BoringSSL)中得到支持。与 JDK 中的现有签名方案相比,EdDSA 具有更高的安全性和性能。这是一个新的功能。使用示例如下:// example: generate a key pair and sign KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519"); KeyPair kp = kpg.generateKeyPair(); // algorithm is pure Ed25519 Signature sig = Signature.getInstance("Ed25519"); sig.initSign(kp.getPrivate()); sig.update(msg); byte[] s = sig.sign(); // example: use KeyFactory to contruct a public key KeyFactory kf = KeyFactory.getInstance("EdDSA"); boolean xOdd = ... BigInteger y = ... NamedParameterSpec paramSpec = new NamedParameterSpec("Ed25519"); EdECPublicKeySpec pubSpec = new EdECPublicKeySpec(paramSpec, new EdPoint(xOdd, y)); PublicKey pubKey = kf.generatePublic(pubSpec);有关EdDSA 数字签名算法的详细内容见RFC 8032规范。2. 封闭类(预览特性)可以是封闭类和或者封闭接口,用来增强 Java 编程语言,防止其他类或接口扩展或实现它们。有了这个特性,意味着以后不是你想继承就继承,想实现就实现了,你得经过允许才行。示例如下:public abstract sealed class Student permits ZhangSan, LiSi, ZhaoLiu { ... }类 Student 被 sealed 修饰,说明它是一个封闭类,并且只允许指定的 3 个子类继承。3. 隐藏类此功能可帮助需要在运行时生成类的框架。框架生成类需要动态扩展其行为,但是又希望限制对这些类的访问。隐藏类很有用,因为它们只能通过反射访问,而不能从普通字节码访问。此外,隐藏类可以独立于其他类加载,这可以减少框架的内存占用。这是一个新的功能。4. 移除了 Nashorn JavaScript 脚本引擎移除了 Nashorn JavaScript 脚本引擎、APIs,以及 jjs 工具。这些早在 JDK 11 中就已经被标记为 deprecated 了,JDK 15 被移除就很正常了。Nashorn 是 JDK 1.8 引入的一个 JavaScript 脚本引擎,用来取代 Rhino 脚本引擎。Nashorn 是 ECMAScript-262 5.1 的完整实现,增强了 Java 和 JavaScript 的兼容性,并且大大提升了性能。那么为什么要移除?官方的解释是主要的:随着 ECMAScript 脚本语言的结构、API 的改编速度越来越快,维护 Nashorn 太有挑战性了,所以……。5. 重新实现 DatagramSocket API重新实现旧版 DatagramSocket API,更简单、更现代的实现来代替java.net.DatagramSocket和java.net.MulticastSocketAPI 的基础实现,提高了 JDK 的可维护性和稳定性。新的底层实现将很容易使用虚拟线程,目前正在 Loom 项目中进行探索。这也是 JEP 353 的后续更新版本,JEP 353 已经重新实现了 Socket API。6. 准备禁用和废除偏向锁在 JDK 15 中,默认情况下禁用偏向锁(Biased Locking),并弃用所有相关的命令行选项。后面再确定是否需要继续支持偏向锁,国为维护这种锁同步优化的成本太高了。7. 模式匹配(第二次预览)第一次预览是 JDK 14 中提出来的,点击这里查看我之前写的详细教程。Java 14 之前用法:if (obj instanceof String) { String s = (String) obj; // 使用s }Java 14之后的用法:if (obj instanceof String s) { // 使用s }Java 15 并没有对此特性进行调整,继续预览特性,只是为了收集更多的用户反馈,可能还不成熟吧。8. ZGC 功能转正ZGC是一个可伸缩、低延迟的垃圾回收器。ZGC 已由JEP 333集成到JDK 11 中,其目标是通过减少 GC 停顿时间来提高性能。借助 JEP 377,JDK 15 将 ZGC 垃圾收集器从预览特性变更为正式特性而已,没错,转正了。这个 JEP 不会更改默认的 GC,默认仍然是 G1。9. 文本块功能转正文本块,是一个多行字符串,它可以避免使用大多数转义符号,自动以可预测的方式格式化字符串,并让开发人员在需要时可以控制格式。文本块最早准备在 JDK 12 添加的,但最终撤消了,然后在 JDK 13 中作为预览特性进行了添加,然后又在 JDK 14 中再次预览,在 JDK 15 中,文本块终于转正,暂不再做进一步的更改。Java 13 之前用法,使用one-dimensional的字符串语法:String html = "<html>\n" + " <body>\n" + " <p>Hello, world</p>\n" + " </body>\n" + "</html>\n";Java 13 之后用法,使用two-dimensional文本块语法:String html = """ <html> <body> <p>Hello, world</p> </body> </html> """;10. Shenandoah 垃圾回收算法转正Shenandoah 垃圾回收从实验特性变为产品特性。这是一个从 JDK 12 引入的回收算法,该算法通过与正在运行的 Java 线程同时进行疏散工作来减少 GC 暂停时间。Shenandoah 的暂停时间与堆大小无关,无论堆栈是 200 MB 还是 200 GB,都具有相同的一致暂停时间。JDK 15 Shenandoah垃圾收集器从预览特性变更为正式特性而已,没错,又是转正了。11. 移除了 Solaris 和 SPARC 端口。移除了 Solaris/SPARC、Solaris/x64 和 Linux/SPARC 端口的源代码及构建支持。这些端口在 JDK 14 中就已经被标记为 deprecated 了,JDK 15 被移除也不奇怪。12. 外部存储器访问 API(二次孵化)这个最早在 JDK 14 中成为孵化特性,JDK 15 继续二次孵化并对其 API 有了一些更新。目的是引入一个 API,以允许 Java 程序安全有效地访问 Java 堆之外的外部内存。这同样是 Java 14 的一个预览特性。13. Records Class(二次预览)Records Class 也是第二次出现的预览功能,它在 JDK 14 中也出现过一次了,使用 Record 可以更方便的创建一个常量类,使用的前后代码对比如下。旧写法:class Point { private final int x; private final int y; Point(int x, int y) { this.x = x; this.y = y; } int x() { return x; } int y() { return y; } public boolean equals(Object o) { if (!(o instanceof Point)) return false; Point other = (Point) o; return other.x == x && other.y = y; } public int hashCode() { return Objects.hash(x, y); } public String toString() { return String.format("Point[x=%d, y=%d]", x, y); } }新写法:record Point(int x, int y) { }也就是说在使用了 record 之后,就可以用一行代码编写出一个常量类,并且这个常量类还包含了构造方法、toString()、equals() 和 hashCode() 等方法。14. 废除 RMI 激活废除 RMI 激活,以便在将来进行删除。需要说明的是,RMI 激活是 RMI 中一个过时的组件,自 Java 8 以来一直是可选的。参考引用本文同步至: https://waylau.com/jdk-15-released/https://jdk.java.net/15/release-noteshttps://openjdk.java.net/projects/jdk/15/https://openjdk.java.net/projects/jdk/15/spec/《Java核心编程》https://github.com/waylau/modern-java-demos转载自:https://my.oschina.net/waylau/blog/4633203
23
2020-09
视频学习
全部|产品宣传|功能介绍|开发教程
论坛热帖
1
2
开发者社区