- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
(这主要是一个历史问题。Pivotal 建议所有论坛讨论都在 StackOverflow 上进行,这就是我在这里问它的原因。)
Spring Boot 项目用来证明将应用程序的类和依赖项从可执行 jar 格式的“顶层”移动到 BOOT-INF/
下面的原因是什么? ?
只是想猜测一下,这似乎可以很容易地使用简单的 java -xf the-jar.jar BOOT-INF/classes
从 fat jar 中仅提取与应用程序相关的类和 jar。命令。是这样吗?还有其他原因吗?
最佳答案
TL;博士
在 jar 的根目录中打包应用程序类需要 Spring Boot 的类加载器使用非常规的委托(delegate)模型,并且还会导致 Java 代理出现问题。
详细解释
当使用 java -jar
启动 jar 文件时jar 根目录中的所有类都在系统类加载器的类路径上。在 Spring Boot fat jar 中,这包括启动器的类,该类负责创建一个类加载器,该类加载器可以加载应用程序的类及其嵌套在 fat jar 中的依赖项。
在 Spring Boot 1.3 及更早版本中,应用程序类被打包在一个 fat jar 文件的根目录中。这意味着它们位于系统类加载器的类路径上。使用标准的父优先委托(delegate)模型,这意味着应用程序类将由系统类加载器而不是 Spring Boot 的类加载器加载。这是有问题的,因为只有 Spring Boot 的类加载器可以从嵌套在 fat jar 中的依赖项加载类。结果是应用程序无法加载其任何依赖项的类。
Spring Boot 1.3 通过对其类加载器使用非常规的委托(delegate)模型克服了这个问题。它使用来自系统类加载器的 URL 创建了一个新的类加载器,但不使用系统类加载器作为父类——而是使用系统类加载器的父类。这意味着 Spring Boot 的类加载器将用于将应用程序的类加载到 jar 的根目录中,并将应用程序依赖项的类加载到嵌套的 jar 中。
这种方法有一些缺点。首先是它使 Spring Boot 的类加载器变得相当复杂。第二个是它打破了 Java 代理关于如何加载其类的许多假设。我们解决了其中的几个问题,但很明显我们正在打一场失败的战斗。
Spring Boot 1.4 重新排列了一个胖 jar 以将应用程序类放置在 BOOT-INF/classes
中(它还将嵌套的 jar 移动到 BOOT-INF/lib
,但从类加载的角度来看这没有影响)。将应用程序类移动到 BOOT-INF/classes
意味着它们不再位于系统类加载器的类路径上。这意味着 Spring Boot 的类加载器可以配置为从 BOOT-INF/classes
加载类。以及从 BOOT-INF/lib
中的 jar 中并使用系统类加载器作为其父级。 Java 代理可以打包在 jar 的根目录中,系统类加载器将照常从那里加载它们。
如需进一步阅读,您可能对 the commit that introduced the change 上的消息感兴趣以及它所链接的其他问题。
关于spring-boot - 为什么 Spring Boot 1.4 改变了它的 jar 布局来定位 BOOT-INF 下的应用程序类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40292816/
python 3.7 在编写最大值的搜索代码时,我遇到了负无穷大的奇怪行为。 有人可以解释为什么这种行为吗? >>> inf = float('inf') >>> inf is inf True >>
我是 Julia 的新手 - Windows 上的 1.0.0 版。 documentation陈述如下 julia> Inf / Inf NaN 但是当我执行以下操作时,我得到了不同的结果 juli
我是 Julia 的新手 - Windows 上的 1.0.0 版。 documentation陈述如下 julia> Inf / Inf NaN 但是当我执行以下操作时,我得到了不同的结果 juli
我正在使用用 Objective-C 编写的第三个 CocoaPods 库来截取 UITextView 的屏幕截图。 iOS 8 没问题,但在我更改 iOS 9 和 Swift 2 的语法后,它会抛出
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我已经从 Intellij 为 Spark+ scala 代码创建了 jar 并尝试在开发集群中运行该 jar,但最终出现以下错误: Exception in thread "main" java.l
我有一个包含如下标记的 jsp 文件: 在我的应用中,部署结构是: WEB-INF |-lib |-some.jar |-META-INF
我正在尝试在大型数据集 (5000x300) 上运行 randomForest。不幸的是,我收到如下错误消息: > RF df2 df2 character(0) > df2 df2 numer
我想返回 +INF 但我只返回“inf”: int main(void) { double dubb = HUGE_VAL; printf("%f \n", dubb); } 我是不是
我不明白为什么在以下两种情况下除以 0 会产生不同的结果。amort 是一个计算常量摊销计划的函数。我们现在唯一关心的是 A 的最后一个元素恰好为 0。 amort = @(r,M) ((1+r).^
在 C 中,在使用 IEEE-754 float 的实现中,当我比较两个为 NaN 的 float 时,它返回 0 或“false”。但是为什么两个都为 inf 的 float 相等呢? 这个程序打印
以下代码生成结果-inf。 fn main() { println!("{}", (-10. / 0.)); } 但是,当我尝试下面的代码时,它没有打印出 true,而是给我一个错误。 fn
Numpy 的 log 方法为 log(0) 提供 -inf。这个值是可比较的: >>> np.log(0) == np.log(0) True 现在在单元测试中以下工作正常: self.assert
在下一种情况下哪种方法更好: 我需要获取一些按分数排序的元素,我可以使用这两种方法: 1. zrange myZset 1 5 WITHSCORES 2. zrangebyscore myZset
我正在尝试解释 Web 应用程序的基础知识。我在 META-INF 和 WEB-INF 上遇到了这个问题。这些目录是如何获得这些名称的? 最佳答案 Jar 文件实际上是 ZIP 文件,带有额外的信息和
我正在使用修改后的kanderson-well beats委托版本来修改AVKit需要的请求。所有代码将在帖子的底部。修改请求、创建字幕播放列表并将它们添加到主播放列表中是很好的,因为它们在请求AVM
当您有符合 IEEE754 标准的浮点实现时,与 NaN 的任何比较都是 false,即使是 NaN == NaN,但是+inf == +inf 是 true,为什么? 从我的角度来看,说 +inf
R 中是否有一个函数可以确定值是否为 NA , NaN , Inf , -Inf ,否则不是一个格式良好的数字? 最佳答案 你要is.finite > is.finite(NA) [1] FALSE
我们有一个应用程序,我们正在使用 InstallShield LE(Visual Studio 2010 附带的那个)来管理应用程序的安装。 作为安装的一部分,我需要安装一个 INF 文件,以便应用程
我正在将应用程序移植到 tomcat,我怀疑以下类加载可能是个问题... 如果我在 WEB-INF/classes 中有一个类需要一个在 WEB-INF/lib 中的类,他们找不到它。 如果我在 WE
我是一名优秀的程序员,十分优秀!