移除Java 9中的sun.misc.Unsafe会破坏Spring、Hibernate。

问题描述 投票:14回答:4

我读到 此处 如果Oracle删除了Spring和许多其他流行的库,Spring和许多其他流行的库就会崩溃。sun.misc.Unsafe 然而,在Spring和Hibernate中,并没有对这个类的静态引用。那么,这个说法是真的吗?

另外,有64个引用到 Unsafe 在Java 8中,但如果Oracle删除该类,他们将更新所有的类,没有库会受到影响(除非他们使用了 Unsafe 直接引用)。)

java spring java-9 unsafe
4个回答
8
投票

马克-莱因霍尔德在2015年JVM语言峰会期间有一个演讲,题目是 sun.misc.不安全的秘密历史和悲惨命运。. 虽然这些会谈有很多免责声明,但你可以在下面看到建议的方法。10:23的描述。JEP260.

总的想法是:

  1. 用更安全、更受支持的API取代现有功能。
  2. 弃用之前的 Unsafe 已被取代的API
  3. 在下个版本中删除过时的代码。

下面是JEP260的一些相关文字(摘自2015年10月20日)。

在JDK 9中,我们建议:

  • 默认封装所有非关键的内部API。定义它们的模块将不会导出其包供外部使用。(作为最后的手段,对这些 API 的访问将在编译时和运行时通过命令行标志提供,除非这些 API 因其他原因被修改或删除。)

  • 以同样的方式并通过同样的最后手段,封装JDK 8中支持替代的关键内部API。支持的替代是指 Java SE 8 标准的一部分(即在 java.* 或 javax.* 包中),或者是 JDK 特有的,并且用 @jdk.Exported 注释(通常在 com.sun.* 或 jdk.* 包中)。

  • 不封装那些在 JDK 8 中不存在支持的替换的关键内部 API,而且,废弃那些在 JDK 9 中支持替换的 API,并打算在 JDK 10 中封装它们,甚至可能将它们删除。

...

... JDK 9 中引入替换的关键内部 API 将在 JDK 9 中被废弃,并在 JDK 10 中封装或删除。


5
投票

也许这些引用不在Spring或Hibernate的核心中,而是在其他地方。链接的文档中说,关于Spring

春天框架(通过Objenesis,有一个回溯)。

我试着在我正在做的项目中搜索Unsafe的用法,所以还是有不少库可能会被破坏。

快速搜索的结果。

  • Guava
  • GWT
  • Netty
  • 泽西岛-普通
  • Infinispan
  • Jboss-Modules

5
投票

这个 资源提供了对JDK 9的现状及其特性的正确理解。社区发起了一场关于不安全及其对java未来发展的影响的讨论。所给出的文档是社区为应对这一问题所做的努力。JEP-260 建议隐藏一些内部API,但允许访问一些关键API,其中包括Unsafe。从文档中提取的。

建议在JDK 9中保留的关键内部API有:

sun.misc.Cleaner

sun.misc.{Signal,SignalHandler}。

sun.misc.Unsafe (该类中许多方法的功能现在可以通过变量句柄 (JEP 193) 获得。)

sun.reflect.Reflection::getCallerClass(该方法的功能可以通过 JEP 259 以标准形式提供。

sun.reflection.ReflectionFactory

所以得出结论,至少是基于 鉴于 JEP,Unsafe应该保留。


3
投票

答案在链接的文档中。Spring没有直接依赖 Unsafe但Spring依赖于Objenesis,而Objenesis依赖于 Unsafe.

Objenesis的依赖性 Unsafe: https:/github.comeasymockobjenesisblobmastermainsrcmainjavaorgobjenesisinstantiatorsunUnsafeFactoryInstantiator.java。

Spring对Objenesis的依赖性本身就有点奇怪。Spring的构建脚本获取Objenesis二进制文件,并使用JarJar工具进行字节码级别的修改。你可以在下面的构建脚本中看到它做了什么。https:/github.comspring-projectsspring-frameworkblobmasterbuild.gradle)。 (在写这篇文章的时候,见326-343行和347行)。

这本质上意味着Spring的 "spring-core "二进制文件最终在org.springframework.objenesis.*包结构下包含了大量的类,但这些类最初是以源代码的形式存储在Objenesis GitHub中,由Objenesis团队以二进制文件的形式发布,在Spring的构建过程中被获取,重新打包成org.springframework.*包,然后作为Spring的一部分重新发布。这就是为什么你找不到它们的原因。

Spring使用 Unsafe (通过Objenesis)来创建类,而不需要先调用构造函数。

© www.soinside.com 2019 - 2024. All rights reserved.