我在这里读到,如果 Oracle 在 Java 9 中删除,Spring 和许多其他流行的库将会中断sun.misc.Unsafe
。但是,在 Spring 或 Hibernate 中没有对此类的静态引用。那么,这种说法是真的吗?
顺便说一句,Java 8 中有 64 个引用Unsafe
,但如果 Oracle 删除了该类,它们将更新所有这些类,并且不会影响任何库(除非它们Unsafe
直接使用)。
Mark Reinhold 在 2015 年 JVM 语言峰会上发表了题为Sun.misc.Unsafe 的秘密历史和悲剧命运的演讲。尽管这些谈话有很多免责声明,但您可以在10:23看到建议的方法,该方法在JEP260中进行了描述。
总体思路是:
Unsafe
弃用已被替换的先前存在的API以下是 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 中封装或删除。
也许这些引用不在 Spring 或 Hibernate 的核心中,而是在其他地方。链接的文件说关于春天
Spring 框架(通过 Objenesis,带有后备)
我试图在我目前正在从事的项目中搜索 Unsafe 的用法,所以仍然有相当多的库可能会损坏。
快速搜索结果:
该资源提供了对 JDK 9 的当前状态及其功能的正确理解。社区开始讨论有关 Unsafe 及其未来的 Java 未来。给定的文档是社区对 JEP-260 做出反应的努力,JEP-260建议隐藏一些内部 API,但让一些关键 API 可访问,其中包括不安全的。从文档本身中提取:
建议在 JDK 9 中保持可访问性的关键内部 API 是:
sun.misc.Cleaner
sun.misc.{信号,信号处理器}
sun.misc.Unsafe (此类中许多方法的功能现在可通过变量句柄 (JEP 193) 获得。)
sun.reflect.Reflection::getCallerClass(此方法的功能可以通过 JEP 259 以标准形式提供。)
sun.reflect.ReflectionFactory
因此,总而言之,至少基于给定的JEP,Unsafe 应该仍然存在。
答案在链接的文档中。Spring 没有直接依赖于Unsafe
,但 Spring 依赖于 Objenesis 而 Objenesis 依赖于Unsafe
.
Objenesis 的依赖关系Unsafe
:https ://github.com/easymock/objenesis/blob/master/main/src/main/java/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java
Spring 对 Objenesis 的依赖本身就有点奇怪。Spring 的构建脚本获取 Objenesis 二进制文件并使用 JarJar 工具进行字节码级别的更改。您可以在以下构建脚本中看到它的作用:https ://github.com/spring-projects/spring-framework/blob/master/build.gradle (在撰写本文时,请参见第 326-343 和 347 行) .
这实质上意味着 Spring 的“spring-core”二进制文件最终包含了 org.springframework.objenesis.* 包结构下的大量类,但这些类最初存储在 Objenesis GitHub 的源代码中,由 Objenesis 团队作为二进制文件发布,在 Spring 构建期间获取,重新打包到 org.springframework.* 包,然后作为 Spring 的一部分重新发布。这就是为什么你很难找到它们。
Spring 使用Unsafe
(通过 Objenesis)创建类而无需先调用构造函数。