滑动拼图验证码操作步骤:

马克·雷因霍尔德(Mark Reinhold)最近提议延迟Java 9,以花更多的时间完成项目Jigsaw,这是即将发布的版本的主要功能。 虽然这个决定肯定会使Java的厄运论者重回舞台,但我个人感到很轻松,并且认为这是一个很好且必要的决定。 Java 9功能完成的里程碑当前设置为12月10日 ,禁止在该日期之后引入新功能 。 但是, 从 Jigsaw项目的早期访问版本来看,Java的模块系统似乎尚未为该开发阶段做好准备。

在最新的Java发布周期中,项目Jigsaw的延迟已成为一种习惯 。 一定不能将其误解为无能,而只能作为一种指示,说明向Java引入模块有多困难,而Java目前对于真正的模块化来说是陌生的。 最初,Java的模块系统是在2008年提出的,以包含在Java 7中。但是直到今天,拼图的实现始终比预期的要困难得多。 在几次停职甚至是暂时的放弃之后,Java的管理员肯定会承受最终成功的压力。 很高兴看到这种压力并没有促使Java团队急于发布。

在本文中,我尝试总结一下Jigsaw项目的状态,并在Jigsaw邮件列表中进行了公开讨论 。 我写这篇文章是为了对当前的讨论做出贡献,并希望让更多的人参与到正在进行的开发过程中。 我无意淡化Oracle所做的艰苦工作。 我在明确声明这一点是为了避免在隐藏sun.misc.Unsafe之后对拼图进行了相当激动的讨论之后,引起了误解。

模块化反射

究竟是什么使Jigsaw项目如此困难? 如今,可见性修饰符是封装类范围的最接近的近似值。 Package-privacy可以用作其包装类型的不完美保留。 但是对于跨越多个程序包的内部API的更复杂的应用程序,可见性修饰符不足,因此需要真正的模块。 使用项目Jigsaw,可以真正封装类,这使得即使某些类被声明为公共类,某些代码也无法使用它们。 但是,基于所有类在运行时始终可用的假设下构建的Java程序可能需要进行根本性的更改。

对于最终用户应用程序的开发人员而言,此更改的根本性可能不如Java库和框架的维护人员。 库通常在编译过程中不知道其用户代码。 为了克服此限制,库可以回退到使用反射。 这样,用于依赖项注入的容器(例如Spring)可以实例化应用程序的bean实例,而框架在编译时并不知道bean类型。 为了实例化此类对象,容器只需将其工作延迟到运行时,直到它扫描应用程序的类路径并发现现在可见的bean类型。 对于这些类型中的任何一种,框架都将定位一个构造函数,该构造函数在解析所有注入的依赖项后会进行反射性调用。

一长串Java框架使用与反射配对的运行时发现。 但是在模块化环境中,如果不解决模块边界问题,就无法再运行以前的运行时分辨率。 使用项目Jigsaw,Java运行时断言每个模块仅访问在访问模块的描述符中声明为依赖项的模块。 此外,导入的模块必须将相关的类导出到其访问器。 依赖项注入容器的模块化版本无法将任何用户模块声明为依赖项,因此禁止进行反射访问。 实例化未导入的类时,这将导致运行时错误。

为了克服此限制,Jigsaw项目添加了一个新的API,该API允许在运行时包括其他模块依赖性。 使用此API并添加所有用户模块后,模块化的依赖项注入容器现在可以继续实例化在编译时不知道的bean类型。

但是这个新的API真的可以解决问题吗? 从纯粹的功能角度来看,此附加API允许迁移库以保留其功能,即使将其重新包装为模块也是如此。 但是不幸的是,模块边界的运行时强制要求在使用大多数反射代码之前先进行仪式舞蹈。 在调用方法之前,调用者需要始终确保相应的模块已经是调用者的依赖项。 如果框架忘记添加此检查,则会在编译期间抛出运行时错误而不会被发现。

由于许多库和框架都过度使用了反射,因此可访问性的这种变化不太可能改善运行时封装。 即使安全管理器会限制框架添加运行时模块依赖性,但强制执行此类边界可能会破坏大多数现有应用程序。 更现实的是,大多数违反模块边界的行为并不表示真正的错误,而是由代码迁移不当引起的。 同时,如果大多数框架抢占了对大多数用户模块的访问权限,则运行时限制不可能改善封装。

当模块对自己的类型使用反射时,此要求当然不适用,但是在实践中这种反射的使用非常少见,并且可以通过使用多态来代替。 在我眼中,在使用反射时强制执行模块边界与它的主要用例相抵触,并使本来就不容易的反射API更加难以使用。

模块化资源

除了这个限制,目前还不清楚依赖注入容器将如何发现它应该实例化的类。 在非模块化应用程序中,框架可以例如期望类路径上存在给定名称的文件。 然后,此文件用作描述如何发现用户代码的入口点。 通常,通过从类加载器请求命名资源来获取此文件。 对于项目Jigsaw,当所需的资源也封装在模块的边界内时,这将不再可能。 据我所知,资源封装的最终状态尚未完全确定。 但是,在尝试当前的早期访问版本时,无法访问外部模块的资源。

当然,拼图项目的当前草案中也解决了这个问题。 为了克服模块边界,已授予Java 预先存在的ServiceLoader类超能力。 为了使特定的类可用于其他模块,模块描述符提供了一种特殊的语法,该语法允许通过模块边界泄漏某些类。 应用此语法,框架模块声明它提供了某种服务。 然后,用户库声明框架可以访问同一服务的实现。 在运行时,框架模块使用服务加载器API查找其服务的任何实现。 这可以用作在运行时发现其他模块的方式,并且可以替代资源发现。

乍看之下,这种解决方案似乎很优雅,但我仍然对此提议表示怀疑。 服务加载程序API的使用非常简单,但同时,其功能也非常有限。 此外,很少有人将其改编成自己的代码,这可以视为其范围有限的指示。 不幸的是,只有时间能证明此API是否能够充分容纳所有用例。 同时,可以将单个Java类与Java运行时紧密地联系在一起,从而几乎不可能弃用和替换服务加载程序API。 在Java的历史背景下,已经讲述了许多看起来不错但又变酸的想法,我发现创建这样一个神奇的中心很容易成为现实,它很容易成为实现瓶颈。

最后,还不清楚如何在模块化应用程序中公开资源。 尽管Jigsaw不会破坏任何二进制兼容性,但从以前一直返回值的ClassLoader::getResource调用返回null可能只是将应用程序埋在成堆的null指针异常之下。 例如,代码操纵工具需要一种方法来定位类文件,这些类文件现在已经封装起来,这至少会阻碍它们的采用过程。

可选依赖项

服务加载器API无法容纳的另一个用例是可选依赖项的声明。 在许多情况下,可选的依赖项不被认为是一种好习惯,但实际上,如果可以将依赖项组合成大量排列,它们提供了一种便捷的方法。

例如,如果特定依赖项可用,则库可能能够提供更好的性能。 否则,它将退回到另一个不太理想的选择。 为了使用可选的依赖关系,需要库根据其特定的API进行编译。 但是,如果此API在运行时不可用,则库需要确保永不执行可选代码,并退回到可用的默认值。 这样的可选依赖关系无法在模块化环境中表示,即使从未使用过依赖关系,该环境也可以在应用程序启动时验证任何声明的模块依赖关系。

可选依赖项的一个特殊用例是可选注释包。 今天,Java运行时将批注视为可选的元数据。 这意味着,如果类加载器无法定位注释的类型,则Java运行时将仅忽略所关注的注释,而不是抛出NoClassDefFoundError 。 例如, FindBugs应用程序提供了一个注释包,用于在用户发现所讨论的代码为假阳性后抑制潜在的错误。 在应用程序的常规运行期间,不需要特定于FindBugs的注释,因此它们不包含在应用程序包中。 但是,在运行FindBugs时,该实用程序会显式添加注释包,以使注释可见。 在拼图项目中,这不再可能。 仅当模块声明对注释包的依赖性时,注释类型才可用。 如果以后在运行时缺少此依存关系,则尽管注释不相关,也会引发错误。

非模块化

当然,不将框架捆绑为Java 9中的模块是避免所有讨论的限制的最简单方法。 Java运行时将任何未模块化的jar文件视为类加载器的所谓未命名模块的一部分 。 这个未命名的模块定义了对正在运行的应用程序中存在的所有其他模块的隐式依赖性,并将其所有程序包导出到任何其他模块。 当混合模块化和非模块化代码时,这可以作为备用。 由于未命名模块的隐式导入和导出,所有未迁移的代码应继续像以前一样运行。

虽然这种选择退出可能是沉重反射框架的最佳解决方案,但缓慢采用项目Jigsaw确实也使模块系统的目的无法实现。 由于时间的缺乏是大多数开源项目的主要限制,因此很可能会出现这种结果。 此外,许多开源开发人员都必须将其库编译为旧版Java。 由于模块化和非模块化代码的运行时行为不同,框架将需要维护两个分支,以便能够使用Java 9 API遍历模块化捆绑包中的模块边界。 许多开源开发人员不太可能花时间来使用这种混合解决方案。

代码检测

在Java中,反射方法访问不是库与未知用户代码进行交互的唯一方法。 使用工具API ,可以重新定义类以包含其他方法调用。 例如,这通常用于实现方法级别的安全性或收集代码指标。

在检测代码时,通常会在类加载器加载Java类的类文件之前立即对其进行更改。 由于通常在紧接类加载之前应用类转换,因此当前无法预先更改模块图,因为未加载的类的模块是未知的。 如果检测代码在首次使用之前无法访问已加载的类,则可能会导致无法解决的冲突无法解决。

摘要

软件估算很困难,我们所有人都倾向于低估应用程序的复杂性。 Jigsaw项目对Java应用程序的运行时行为进行了根本性的更改,将发布推迟到彻底评估所有可能性是完全合理的。 当前,悬而未决的问题太多了,这是延迟发布日期的不错选择。

我希望模块边界完全不由运行时强制执行,而是保留为编译器构造。 尽管存在一些缺陷,Java平台已经实现了泛型类型的编译时擦除,并且该解决方案运行良好。 如果没有运行时强制实施,则在JVM上采用动态语言的模块也将是可选的,因为与Java中相同的模块化形式可能没有意义。 最后,我认为当前严格的运行时封装形式试图解决一个不存在的问题。 在使用Java多年之后,我很少遇到无意间使用内部API引起严重问题的情况。 相比之下,我记得在很多情况下滥用本应为私有的API可以解决我无法解决的问题。 同时,Jigsaw仍无法解决Java中缺少模块的其他症状(通常称为jar hell) ,Jigsaw不能区分模块的不同版本。

最后,我认为向后兼容性的适用范围超出了二进制级别。 实际上,二进制不兼容通常比行为更改更容易处理。 在这种情况下,Java多年来成就斐然。 因此,方法合同应与二进制兼容性一样受到高度重视。 尽管项目Jigsaw从技术上讲不会通过提供未命名的模块来破坏方法契约,但是模块化基于其绑定对代码行为进行了微妙的更改。 我认为,这将使经验丰富的Java开发人员和新手都感到困惑,并导致重新出现运行时错误。

这就是为什么我发现强制运行时模块边界的价格与其提供的好处相比过高的原因。 OSGi是一个具有版本控制功能的运行时模块系统,适用于确实需要模块化的用户。 作为一个很大的好处,OSGi在虚拟机之上实现,因此不会影响VM行为。 另外,我认为Jigsaw可以为库提供一种规范的方式,使其在有意义的情况下选择退出运行时约束,例如对于大量反射的库。

翻译自: https://www.javacodegeeks.com/2015/12/project-jigsaw-incomplete-puzzle.html

滑动拼图验证码操作步骤:

滑动拼图验证码操作步骤:_拼图项目:一个不完整的难题相关推荐

  1. 滑动拼图验证码操作步骤:_拼图项目:延期的后果

    滑动拼图验证码操作步骤: Mark Reinhold先生于2012年7月宣布 ,他们计划从Java 8撤消Jigsaw项目 ,因为Jigsaw计划于2013年9月(从现在开始一年)推迟其发布. 这个日 ...

  2. 红外测试操作步骤_红外传感实验操作步骤及数据分析(无测试实图)

    红外传感实验操作步骤及数据分析(无测试实图) 1. 启动红外传感模块 红外传感模块工作实图 ( 1 ) 将 NEWlab 实验硬件平台通电并与电脑链接. ( 2 ) 将红外传感模块放置在 NEWlab ...

  3. 详细说明通过kettke对csv文件转换的操作步骤_如何将多页面pdf分割成一页一页的PDF文件...

    经常会有小伙伴问我,如何将多页面的PDF文件拆分成一个个的PDF文件?例如有5个页面的PDF文件,一次性拆分导出生成5个单页面的PDF文件? PDF文件是我们日常工作学习中经常要用到的,有时候PDF文 ...

  4. 超图软件试用许可操作步骤_软件中的操作步骤

    超图软件试用许可操作步骤 The software comprises of three things: Program code, Documentation, and the Operating ...

  5. 红外测试操作步骤_近红外光谱仪操作步骤_近红外光谱仪波长范围

    近红外光谱仪操作步骤 近红外光谱仪将是一个低成本,方便的选择,可取代FT-IR或同类技术的系统.采用高性能的光学平台,具有较低的电子噪声和多个光栅的选择.紧凑的平台设计即插即用的通讯接口,多种测量范围 ...

  6. win7系统添加wifi连接到服务器,教你win7系统wifi无法连接服务器1237的操作步骤_

    win7系统有很多人都喜欢使用,我们操作的过程中常常会碰到win7系统wifi无法连接服务器1237的问题.如果遇到win7系统wifi无法连接服务器1237该怎么办呢?很多电脑水平薄弱的网友不知道w ...

  7. ae如何把已有图片当做蒙版_用ae的蒙版给图片部分图像填充颜色的具体操作步骤_怎样在ae加蒙版_AE蒙版如何改颜色_2019最新完整版教程详解_9号资讯...

    第 2 页 用ae的蒙版给图片部分图像填充颜色的具体操作步骤 如何用ae的MASK(蒙版)给图片部分图像填充颜色? 1.把图片素材(ABC图片)拖动软件界面这里来,并新建ABC合成. 在图层面板这里, ...

  8. c语言拼图验证码编写,java实现拼图验证码

    最近项目需要将原有的图形验证码更换为拼图验证,开始去网上搜了一些相关的DEMO,发现做这个的DEMO很少.不得已,只能自己慢慢摸索啦. 经过几天的坑,算是基本完成了需求.现分享下实现的过程 DEMO效 ...

  9. cnn验证码识别代码_中文项目:快速识别验证码,CNN也能为爬虫保驾护航

    原标题:中文项目:快速识别验证码,CNN也能为爬虫保驾护航 机器之心专栏 作者:Nick Li 随着卷积网络的推广,现在有各种各样的快捷应用,例如识别验证码和数学公式等.本文介绍了一个便捷的验证码识别 ...

最新文章

  1. 2020 AI DEBATE即将召开, Judea Pearl、李飞飞等10多位顶级科学家参与 | AI日报
  2. 简单自学机器学习理论——正则化和偏置方差的权衡 (Part III )
  3. 版本发布后软件测试人员要做的工作
  4. 【Java注解系列】内置注解与AOP实现自定义注解
  5. C++学习笔记5[函数]
  6. Spring MVC @ModelAttribute 详解
  7. 关于页面之间传参时有空格,中文及点击页面后退按钮的问题
  8. 结束oracle import,Oracle 结束 imp/exp 和 expdp/impdp 进程的正确方法
  9. 1.JasperReports学习笔记1-了解JasperReports
  10. mysqld:表mysql.plugin不存在_99%测试工程师不知道的数据库知识|干货
  11. WinRAR 命令行简体中文说明
  12. JS 操作cookie
  13. 利用批处理程序和excel获取windows文件信息
  14. php毛玻璃,CSS实现毛玻璃透明效果
  15. 怎样用计算机演示声音的波形,趣味物理实验 用计算机观察声音的波形
  16. jeesit的简单使用(四)
  17. 《社会调查数据管理——基于Stata 14管理CGSS数据》一导读
  18. QTableView遍历
  19. 交换机trunk模式工作原理
  20. java long 多少位_long long 可以支持多少位的数?

热门文章

  1. P6672-[清华集训2016]你的生命已如风中残烛【结论】
  2. P2150-[NOI2015]寿司晚宴【dp】
  3. P4343-[SHOI2015]自动刷题机【二分答案】
  4. codeforces82 D. Two out of Three(记忆化搜索)
  5. 【动态规划】城市交通
  6. 27、jdbc操作数据库(4)
  7. 1、jquery事件绑定和委托的实现
  8. 从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的?
  9. Java集合从菜鸟到大神演变
  10. 如何求解两个数的最大公约数